<?php

namespace App\Http\Controllers\Api\v1;

use App\Components\Functions;
use App\Events\LogAction;
use App\Jobs\SendMailRentersMoney;
use App\Jobs\SendMessageBot;
use App\Jobs\SendMessageBotV2;
use App\Jobs\SendMessageV2;
use App\Jobs\SendNotificationMessage;
use App\Models\CollectSpend;
use App\Models\CollectSpendCycle;
use App\Models\CollectSpendFile;
use App\Models\Config;
use App\Models\ConfigHostel;
use App\Models\Contract;
use App\Models\ContractFee;
use App\Models\Conversation;
use App\Models\Deposit;
use App\Models\ElectricWater;
use App\Models\Extra;
use App\Models\Hostel;
use App\Models\HostelFee;
use App\Models\Message;
use App\Models\MoneyDetail;
use App\Models\MoneyInfo;
use App\Models\Notification;
use App\Models\Receiver;
use App\Models\Renter;
use App\Models\RenterRoom;
use App\Models\Room;
use App\Models\RoomBed;
use App\Models\RoomFee;
use App\Models\RoomReservation;
use App\Models\Statistic;
use App\Models\StatisticLog;
use App\Models\Transaction;
use App\Models\TypeCollect;
use App\Models\TypeSpend;
use App\User;
use Barryvdh\DomPDF\Facade as PDF;
use Carbon\Carbon;

use Dompdf\Dompdf;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;


use Pusher\Pusher;
use Spipu\Html2Pdf\Html2Pdf;

class MoneyController extends BaseController
{
    //

    protected $pusher;

    public function __construct()
    {
        parent::__construct();

        $this->pusher = \PusherService::getClient();
    }

    /**
     * @api {get} /get-spend Danh sách phiếu chi
     * @apiName /get-spend
     * @apiGroup Money
     * @apiParam {String} start_date m/Y
     * @apiParam {String} enđ_date m/Y
     * @apiParam {String} hostel_id
     * @apiParam {String} room_id
     *
     * @apiDescription Api Danh sách thu tiền phòng
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getSpend(Request $request)
    {
        $ownerId = $this->user->id;
        $user = $this->user;
        $hostelArrs = Hostel::query()->where('owner_id', $ownerId)->pluck('id')->toArray();

        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
            $hostelArrs = Functions::getHostelArrStaffApi($this->user);
        }

        $retVal = [];

        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $hostelId = $request->input('hostel_id');
        $roomId = $request->input('room_id');
        $userId = $request->input('user_id');

        $times = CollectSpend::query()
            ->select(\DB::raw('MONTH(collect_spends.date_action) as month, YEAR(collect_spends.date_action) as year, collect_spends.date_action'))
            ->where('owner_id', $ownerId)
            ->when(!empty($userId), function ($q) use ($userId) {
                $q->where('user_id', $userId);
            })
            ->where('collect_spends.type', CollectSpend::SPEND);

        $isMonth = true;

        if (!empty($startDate)) {
            try {
                $startDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$startDate)->startOfMonth()->toDateString();
            } catch (\Exception $exception) {
                $isMonth = false;
                $startDateAction = Carbon::createFromFormat('d/m/Y', $startDate)->startOfDay()->toDateString();
            }

            $times = $times->where('collect_spends.date_action', '>=', $startDateAction);
        }

        if (!empty($endDate)) {
            try {
                $endDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$endDate)->endOfMonth()->toDateString();
            } catch (\Exception $exception) {
                $isMonth = false;
                $endDateAction = Carbon::createFromFormat('d/m/Y', $endDate)->endOfDay()->toDateString();
            }

            $times = $times->where('collect_spends.date_action', '<=', $endDateAction);
        }

        $times = $times->when(!empty($hostelId), function ($q) use ($hostelId) {
            $q->where('collect_spends.hostel_id', $hostelId);
        });

        if (!empty($roomId)) {
            $times = $times->where('collect_spends.room_id', $roomId);
        }

        $times = $times->groupBy(\DB::raw('month, year'))->orderBy('date_action', 'desc')->get();

        foreach ($times as $time) {

            $month = $time->month;
            $year = $time->year;

            $startTime = null;
            $endTime = null;
            if ($isMonth) {
                $startTime = Carbon::createFromFormat('d/m/Y', '01/' . $time->month . '/' . $time->year)->startOfMonth()->toDateTimeString();
                $endTime = Carbon::createFromFormat('d/m/Y', '01/' . $time->month . '/' . $time->year)->endOfMonth()->toDateTimeString();
            } else {
                if (!empty($startDateAction) && !empty($endDateAction)) {
                    $startTime = $startDateAction;
                    $endTime = $endDateAction;
                }
            }

            $items = CollectSpend::query()
                ->with('cycle')
                ->select(\DB::raw('collect_spends.*'))
                ->when(!empty($userId), function ($q) use ($userId) {
                    $q->where('user_id', $userId);
                })
                ->where('collect_spends.type', CollectSpend::SPEND);
            $items = $items
                ->with('hostel')
                ->with('files')
                ->where(function ($q) use ($hostelArrs, $ownerId, $user) {
                    if ($user->type == User::OWNER) {
                        $q->where('owner_id', $ownerId);
                    } else {
                        $q->orWhereIn('hostel_id', $hostelArrs);
                        $q->orWhere('user_id', $user->id);
                    }
                });

            if (!empty($startTime) && !empty($endTime)) {
                $items = $items->whereBetween('collect_spends.date_action', [$startTime, $endTime]);
            }

            if (!empty($hostelId)) {
                $items = $items->where('collect_spends.hostel_id', $hostelId);
            }

            if (!empty($roomId)) {
                $items = $items->where('collect_spends.room_id', $roomId);
            }

            $items = $items
                ->orderBy('collect_spends.id', 'desc')
                ->get();

            foreach ($items as $item) {
                if ($item->hostel) {
                    $item->hostel_name = $item->hostel->name;
                } else {
                    $item->hostel_name = '';
                }
                $item->type_name = Functions::getTypeCpName($item);
            }

            $itemVal = [
                'time' => 'Tháng ' . $month . '/' . $year,
                'histories' => $items
            ];

            $retVal[] = $itemVal;
        }

        return response([
            'status' => 1,
            'data' => $retVal
        ]);

    }

    /**
     * @api {get} /get-collect Danh sách phiếu thu
     * @apiName /get-collect
     * @apiGroup Money
     * @apiParam {String} start_date m/Y
     * @apiParam {String} enđ_date m/Y
     * @apiParam {String} hostel_id
     * @apiParam {String} room_id
     *
     * @apiDescription Api Danh sách thu tiền phòng
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getCollect2(Request $request)
    {
        $ownerId = $this->user->id;
        $user = $this->user;
        $hostelArrs = Hostel::query()->where('owner_id', $ownerId)->pluck('id')->toArray();
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
            $hostelArrs = Functions::getHostelArrStaffApi($this->user);
        }
        $retVal = [];

        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $hostelId = $request->input('hostel_id');
        $roomId = $request->input('room_id');
        $userId = $request->input('user_id');

        $times = CollectSpend::query()
            ->select(\DB::raw('MONTH(collect_spends.date_action) as month, YEAR(collect_spends.date_action) as year'))
            ->where('owner_id', $ownerId)
            ->where('collect_spends.type', CollectSpend::COLLECT);

        $isMonth = true;

        if (!empty($startDate)) {
            try {
                $startDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$startDate)->startOfMonth()->toDateString();
            } catch (\Exception $exception) {
                $isMonth = false;
                $startDateAction = Carbon::createFromFormat('d/m/Y', $startDate)->startOfDay()->toDateString();
            }

            $times = $times->where('collect_spends.date_action', '>=', $startDateAction);
        }

        if (!empty($endDate)) {
            try {
                $endDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$endDate)->endOfMonth()->toDateString();
            } catch (\Exception $exception) {
                $isMonth = false;
                $endDateAction = Carbon::createFromFormat('d/m/Y', $endDate)->endOfDay()->toDateString();
            }

            $times = $times->where('collect_spends.date_action', '<=', $endDateAction);
        }

        if (!empty($hostelId)) {
            $times = $times->where('collect_spends.hostel_id', $hostelId);
        }

        //dump($isMonth);
        if (!empty($roomId)) {
            $times = $times->where('collect_spends.room_id', $roomId);
        }
        $times = $times->groupBy(\DB::raw('month, year'))->orderBy('year', 'desc')->orderBy('month', 'desc')->get();

        $sum = 0;

        foreach ($times as $time) {

            $month = $time->month;
            $year = $time->year;

            $startTime = null;
            $endTime = null;

            if ($isMonth) {
                $startTime = Carbon::createFromFormat('d/m/Y', '01/' . $time->month . '/' . $time->year)->startOfMonth()->toDateTimeString();
                $endTime = Carbon::createFromFormat('d/m/Y', '01/' . $time->month . '/' . $time->year)->endOfMonth()->toDateTimeString();
            } else {
                if (!empty($startDateAction) && !empty($endDateAction)) {
                    $startTime = $startDateAction;
                    $endTime = $endDateAction;
                }
            }

            $items = CollectSpend::query()->select(\DB::raw('collect_spends.*'))
                ->when(!empty($userId), function ($q) use ($userId) {
                    $q->whereHas('user', function ($q) use ($userId) {
                        $q->where('id', '=', $userId);
                    });
                })
                ->where('collect_spends.type', CollectSpend::COLLECT);
            $items = $items
                ->with('hostel')
                ->with('contract')
                ->with('user')
                ->with('files')
                ->where(function ($q) use ($hostelArrs, $ownerId, $user) {
                    if ($user->type == User::OWNER) {
                        $q->where('owner_id', $ownerId);
                    } else {
                        $q->orWhereIn('hostel_id', $hostelArrs);
                        $q->orWhere('user_id', $user->id);
                    }
                });
            if (!empty($startTime) && !empty($endTime)) {
                $items = $items->whereBetween('date_action', [$startTime, $endTime]);
            }

            if (!empty($hostelId)) {
                $items = $items->where('collect_spends.hostel_id', $hostelId);
            }
            if (!empty($roomId)) {
                $items = $items->where('collect_spends.room_id', $roomId);
            }

            $items = $items->orderBy('collect_spends.id', 'desc')->get();

            foreach ($items as $item) {
                if ($item->hostel) {
                    $item->hostel_name = $item->hostel->name;
                    unset($item->hostel);
                } else {
                    $item->hostel_name = '';
                }
                $item->type_name = Functions::getTypeCpName($item);

                $sum += $item->amount;
                if ($item->user) {
                    $userArr = $item->user->toArray();
                    $userArr['name'] = $item->user->name_text;
                    unset($item->user);
                    $item->user = $userArr;
                }
            }

            $itemVal = [
                'time' => 'Tháng ' . $month . '/' . $year,
                'histories' => $items
            ];

            $retVal[] = $itemVal;
        }

        return response([
            'status' => 1,
            'sum' => $sum,
            'data' => $retVal,
            //
        ]);

    }

    /**
     * @api {get} /get-detail-collect-spend Chi tiết thu chi
     * @apiName /get-detail-collect-spend
     * @apiGroup Money
     * @apiParam {String} id
     *
     * @apiDescription Api Chi tiết thu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function detailCp(Request $request)
    {

        $id = $request->input('id');
        $item = CollectSpend::find($id);
        if (!$item) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }
        if ($item->hostel) {
            $item->hostel_name = $item->hostel->name;
            unset($item->hostel);
        } else {
            $item->hostel_name = '';
        }
        $item->type_name = Functions::getTypeCpName($item);
        if ($item->user) {
            $userArr = $item->user->toArray();
            $userArr['name'] = $item->user->name_text;
            unset($item->user);
            $item->user = $userArr;
        }

        return response([
            'status' => 1,
            'data' => $item,
            //
        ]);

    }

    /**
     * @api {get} /remain-contract Lấy danh sách các hóa đơn chưa thanh toán hết của hợp đồng
     * @apiName remain-contract
     * @apiGroup Money
     * @apiDescription Api Lấy danh sách các hóa đơn chưa thanh toán hết của hợp đồng
     * @apiParam {String} contract_id
     * @apiParam {String} end_contract_date Dạng d/m/Y
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */


    public function getPaymentRemainContract(Request $request)
    {

        $contractId = $request->input('contract_id');

        $endContractDate = $request->input('end_contract_date');

        if (empty($endContractDate)) {
            $endContractDate = Carbon::now();
        } else {
            $endContractDate = Carbon::createFromFormat('d/m/Y', $endContractDate);
        }

        $contract = Contract::find($contractId);

        if (!$contract) {
            return response([
                'status' => 1,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $roomId = $contract->room_id;

        $items = MoneyInfo::query()->select(\DB::raw('id, room_id, remain, user_id, date_action, CONCAT(MONTH(date_action),"/", YEAR(date_action)) as date_action_group, 
        MONTH(date_action) as month, YEAR(date_action) as year'))
            ->where('room_id', $roomId)
            ->where('remain', '>', 0)
            ->where(function ($q) use ($contract) {

                $q->orwhere('user_id', $contract->renter_id);
                $q->orWhere('contract_id', $contract->id);

            })
            ->groupBy(\DB::raw('MONTH(date_action), YEAR(date_action)'))
            ->orderBy(\DB::raw('date_action', 'asc'))->get();


        $itemsRoomPrice = MoneyInfo::query()->where('room_id', $roomId)
            ->where(function ($q) use ($contract) {

                $q->orwhere('user_id', $contract->renter_id);
                $q->orWhere('contract_id', $contract->id);

            })->whereIn('type', [
                MoneyInfo::VOUCHER_ROOM_PRICE,
                MoneyInfo::VOUCHER_CONTRACT
            ])->pluck('id')->toArray();

        $moneyDetails = MoneyDetail::query()->whereIn('money_info_id', $itemsRoomPrice)
            ->orderBy('end_date', 'desc')->first();

        // $endDate = null;
        $endDate = null;
        if ($moneyDetails) {
            $latestEndDate = $moneyDetails->end_date;
            if (!empty($latestEndDate)) {
                $endDate = Carbon::createFromFormat('Y-m-d', $latestEndDate)->addDay();
            }
        }

        $retVal = [];
        $sum = 0;
        $amount = 0;
        $payAmount = 0;
        $extraPrice = 0;
        foreach ($items as $item) {
            $month = $item->month;
            $year = $item->year;

            $startDate = Carbon::createFromFormat('d/m/Y', '01/' . $item->month . '/' . $item->year)->startOfMonth()->toDateTimeString();
            $endDate2 = Carbon::createFromFormat('d/m/Y', '01/' . $item->month . '/' . $item->year)->endOfMonth()->toDateTimeString();

            $histories = MoneyInfo::where('remain', '>', 0);

            if ($this->user) {
                if ($this->user->type == User::OWNER) {
                    $hostels = Hostel::where('owner_id', $this->user->id)->pluck('id')->toArray();
                    $histories = $histories->whereIn('hostel_id', $hostels);
                }
            }

            if (!empty($hostelId)) {
                $histories = $histories->where('hostel_id', $hostelId);
            }

            if (!empty($roomId)) {
                $histories = $histories->where('room_id', $roomId);
            }

            $histories = $histories->whereBetween('date_action', [$startDate, $endDate2])
                ->where(function ($q) use ($contract) {

                    $q->orwhere('user_id', $contract->renter_id);
                    $q->orWhere('contract_id', $contract->id);

                })
                ->with([
                    'hostel',
                    'room',
                    'contract'
                ])
                ->get();

            foreach ($histories as $history) {

                $contract = $history->contract;
                if ($contract) {

                    $users = RenterRoom::query()->withTrashed()->selectRaw('users.*')->join('users', 'users.id', '=', 'renter_rooms.user_id')
                        ->where('renter_rooms.contract_id', $contract->id)->get();

                    $userArr = [];
                    foreach ($users as $user) {
                        $userArr[] = [
                            'id' => $user->id,
                            'name' => $user->name,
                            'phone' => $user->phone,
                            'email' => $user->email
                        ];
                    }

                    $history->users = $userArr;

                }

                if ($history->hostel_id) {
                    $hostel = $history->hostel;
                    if ($hostel) {
                        $history->hostel_name = $hostel->name;
                    } else {
                        $history->hostel_name = '';
                    }
                } else {
                    $history->hostel_name = '';
                }

                if ($history->room_id) {
                    $room = $history->room;
                    if ($room) {
                        $history->room_name = $room->name;
                    } else {
                        $history->room_name = '';
                    }
                } else {
                    $history->room_name = '';
                }
                unset($history->hostel);
                unset($history->room);
                $sum += $history->amount - $history->discount;;
                $amount += $history->amount - $history->discount;

                $pay = \App\Components\Functions::calculateAmountForOrder($history->id)['pay'];
                $history->pay = intval($pay);
                $history->remain = $history->amount - $pay - $history->discount;
                $payAmount += $pay;
            }

            $itemVal = [
                'time' => 'Tháng ' . $month . '/' . $year,
                'histories' => $histories
            ];

            $retVal[] = $itemVal;


        }

        $extraName = null;

        if (!empty($endDate)) {
            if (!empty($endContractDate)) {
                if ($endDate->lessThan($endContractDate)) {

                    $extraPrice = \App\Components\Functions::calculateMoneyInRange($contract, $endDate, $endContractDate);
                    // $extraPrice  = Functions::calculateMoneyInRange4( $endDate->copy(), $endContractDate->copy(), $contract->room_price, $contract->day_collect, true );
                    $extraName = 'Thanh toán tiền phòng từ ' . $endDate->format('d/m/Y') . ' đến ' . $endContractDate->format('d/m/Y');
                }
            } else {
                if ($endDate->lessThan(\Carbon\Carbon::now())) {

                    $extraPrice = \App\Components\Functions::calculateMoneyInRange($contract, $endDate, $endContractDate);
                    // 	$extraPrice  = Functions::calculateMoneyInRange4( $endDate->copy(), Carbon::now(), $contract->room_price, $contract->day_collect, true );
                    $extraName = 'Thanh toán tiền phòng từ ' . $endDate->format('d/m/Y') . ' đến ' . Carbon::now()->format('d/m/Y');
                }
            }
        }
        $startDateCollected = null;
        $endDateCollected = null;
        $messageReturnCollected = null;
        $amountCollected = 0;

        $moneyDetails = MoneyDetail::query()->whereIn('money_info_id', $itemsRoomPrice)
            ->orderBy('end_date', 'desc')->first();
        $latestEndDate = optional($moneyDetails)->end_date;

        if (!empty($latestEndDate)) {
            $endDateCarbon = Carbon::createFromFormat('Y-m-d', $latestEndDate);
            $endDate = $endDateCarbon->copy()->addDay();
            $startDate = clone $endContractDate;
            $startDate = $startDate->addDay(1);
            if ($startDate->lessThanOrEqualTo($endDateCarbon)) {
                $amountCollected = Functions::calculateMoneyInRange4($startDate->copy(), $endDateCarbon->copy(), $contract->room_price, $contract->day_collect, true);
                $startDateCollected = $startDate->format('d/m/Y');
                $endDateCollected = $endDateCarbon->format('d/m/Y');
            }
        }


//		if ( ! empty( $lastInvoiceDate ) ) {
//			$startDate       = clone $endContractDate;
//			$startDate       = $startDate->addDay( 1 );
//			$endDateCarbon = Carbon::createFromFormat('Y-m-d', $latestEndDate);
//			$collectToCarbon = Carbon::createFromFormat( 'Y-m-d', $lastInvoiceDate );
//			if ( $startDate->lessThanOrEqualTo( $collectToCarbon ) ) {
//				$amountCollected    = Functions::calculateMoneyInRange3( $startDate, $endDateCarbon, $contract->room_price, $contract->day_collect );
//				$startDateCollected = $startDate->format( 'd/m/Y' );
//				$endDateCollected   = $collectToCarbon->format( 'd/m/Y' );
//			}
//		}

        return response([
            'status' => 1,
            'data' => [
                'items' => $retVal,
                'deposit' => $contract->deposit,
                'amount' => $amount,
                'paid' => $payAmount,
                'extra' => [
                    'name' => $extraName,
                    'price' => $extraPrice,
                ],
                'remain' => $amount + $extraPrice - $contract->deposit - $payAmount,
                'remain_collected' => [
                    'amount' => $amountCollected,
                    'start_date' => $startDateCollected,
                    'end_date' => $endDateCollected
                ]
            ]
        ]);
    }

    public function getCollect(Request $request)
    {
        $ownerId = $this->user->id;
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);

        $items = Transaction::query()->select(\DB::raw('transactions.*'))->where('transactions.type', CollectSpend::COLLECT);
        $items = $items->join('hostels', 'transactions.hostel_id', '=', 'hostels.id')
            ->where('hostels.owner_id', $ownerId);


        $items = $items->orderBy('transactions.id', 'desc')->limit($limit)->offset($offset)->get();

        return response([
            'status' => 1,
            'data' => $items
        ]);

    }

    public function getDebtRooms(Request $request)
    {
        $hostelId = $request->input('hostel_id');

        $hostel = Hostel::find($hostelId);

        if (!$hostel) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }


        $items = MoneyInfo::select(DB::raw('rooms.id, rooms.name, SUM(Remaining) as `sum_remain`'))->join('rooms', 'money_infos.room_id', '=', 'rooms.id')
            ->where('money_infos.hostel_id', $hostelId)
            ->groupBy('money_infos.room_id')
            ->having('sum_remain', '>', 0)->get();

        return response([
            'status' => 1,
            'data' => $items

        ]);

    }

    public function getDebtRoom(Request $request)
    {
        $roomId = $request->input('room_id');

        $room = Room::find($roomId);

        if (!$room) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }


        $items = MoneyInfo::select(\DB::raw('MONTH(date_action) as month, YEAR(date_action) as year'))->where('remain', '>', 0);

        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $roomId = $request->input('room_id');


        if (!empty($startDate) && !empty($endDate)) {
            $startDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$startDate)->startOfMonth()->toDateString();
            $endDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$endDate)->endOfMonth()->toDateString();
            $items = $items->whereBetween('date_action', [$startDateAction, $endDateAction]);

        }

        $items = $items->groupBy(\DB::raw('month, year'))->orderBy('month', 'desc')->orderBy('year', 'desc')->get();

        $retVal = [];
        foreach ($items as $item) {
            $month = $item->month;
            $year = $item->year;

            $startDate = Carbon::createFromFormat('d/m/Y', '01/'.$item->month . '/' . $item->year)->startOfMonth()->toDateTimeString();
            $endDate = Carbon::createFromFormat('d/m/Y', '01/'.$item->month . '/' . $item->year)->endOfMonth()->toDateTimeString();

            $histories = MoneyInfo::query();

            if (!empty($roomId)) {
                $histories = $histories->where('room_id', $roomId);
            }

            $histories = $histories->whereBetween('date_action', [
                $startDate,
                $endDate
            ])->where('remain', '>', 0)->get();

            foreach ($histories as $history) {

                if ($history->room_id) {
                    $room = Room::find($history->room_id);
                    if ($room) {
                        $history->room_name = $room->name;
                    } else {
                        $history->room_name = '';
                    }
                } else {
                    $history->room_name = '';
                }
            }

            $itemVal = [
                'time' => 'Tháng ' . $month . '/' . $year,
                'histories' => $histories
            ];

            $retVal[] = $itemVal;
        }

        return response([
            'status' => 1,
            'data' => $retVal
        ]);

    }

    public function spend(Request $request)
    {
        $data = $request->all();

        $note = $request->input('note');

        $amount = $data['amount'];

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền phải là số'
            ]);
        }


        $hostelId = $data['hostel_id'];

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống nhà trọ'
            ]);
        }


        $dateAction = $data['date_action'];

        if (empty($dateAction)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống ngày chi'
            ]);
        }


        $dateAction = Carbon::createFromFormat('d/m/Y', $dateAction)->toDateString();

        $userId = $this->user->id;

        Transaction::create([
            'amount' => $amount,
            'hostel_id' => $hostelId,
            'date_action' => $dateAction,
            'user_id' => $userId,
            'type' => Transaction::SPEND,
            'note' => $note
        ]);

        return response([
            'status' => 1,
            'message' => 'Tạo chi thành công'
        ]);
    }


    /**
     * @api {get} /create-payment Tạo 1 thanh toán
     * @apiName create-payment
     * @apiGroup Money
     * @apiDescription Tạo 1 thanh toán
     * @apiParam {String} amount
     * @apiParam {String} money_info_id Mã hóa đơn thanh toán
     * @apiParam {String} payer Người thanh toán
     * @apiParam {String} payment_method Phương thức thanh toán. 1 là tiền mặt 2 là chuyển khoản
     * @apiParam {String} date_action d/m/Y Ngày lập phiếu thu
     * @apiParam {String} note Ghi chú
     *
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function createPayment(Request $request)
    {

        $data = $request->all();


        $amount = $data['amount'];
        $moneyInfoId = $data['money_info_id'];
        $payer = $data['payer'];

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }

        if (empty($payer)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống người nộp tiền'
            ]);
        }

        $amount = Functions::filterInputNumber($amount);

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền phải là số'
            ]);
        }

        $moneyInfo = MoneyInfo::find($moneyInfoId);

        if (!$moneyInfo) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if ($amount > $moneyInfo->remain) {
            return response([
                'status' => 0,
                'message' => 'Không được thanh toán vượt quá số tiền còn lại'
            ]);
        }


        $hostelId = $moneyInfo->hostel_id;
        $roomId = $moneyInfo->room_id;

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }


        if (empty($request->input('date_action'))) {
            $dateAction = Carbon::now()->toDateString();
        } else {
            try {
                $dateAction = Carbon::createFromFormat('d/m/Y', $request->input('date_action'))->toDateString();
            } catch (\Exception $exception) {
                $dateAction = Carbon::now()->toDateString();
            }
        }

        $userId = null;
        if ($this->user) {
            $userId = $this->user->id;
        }

        try {
            \DB::beginTransaction();

            $transaction = Transaction::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'date_action' => $dateAction,
                'user_id' => $userId,
                'money_info_id' => $moneyInfoId,
                'type' => CollectSpend::COLLECT,
                'payer' => $payer
            ]);

            $collectSpend = CollectSpend::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'room_id' => $roomId,
                'note' => $data['note'],
                'payment_method' => $data['payment_method'],
                'date_action' => $dateAction,
                'user_id' => $userId,
                'money_info_id' => $moneyInfoId,
                'type' => CollectSpend::COLLECT,
                'transaction_id' => $transaction->id,
                'payer' => $payer
            ]);

            $payload = json_encode([
                'id' => $moneyInfo->id,
                'type' => config('constants.TRANSACTION')
            ]);

            $remain = $moneyInfo->remain - $amount;
            $moneyInfo->pay = $moneyInfo->pay + $amount;
            $moneyInfo->remain = $remain;
            $moneyInfo->save();

            $type = 'phòng';
            if ($moneyInfo->type == MoneyInfo::VOUCHER_SERVICE) {
                $type = 'dịch vụ';
            }

            $room = Room::find($moneyInfo->room_id);

            if ($room) {
                $room->debt = $remain;
                $room->save();

                $notiDate = $moneyInfo->date_action->format('m/Y');

                $renters = RenterRoom::where('room_id', $room->id)->get();
                $contract = $moneyInfo->contract;

                $bedId = $contract->bed_id;
                if(!empty($bedId))
                {
                    // where bed_id
                }

                $renters = RenterRoom::where('contract_id', $moneyInfo->contract_id)->get();
//                $contract = $moneyInfo->contract;
//                $bedId = $contract->bed_id;
//                if(!empty($bedId))
//                {
//                    // where bed_id
//                    $renters = RenterRoom::where('contract_id', $room->id)->where('bed_id', $bedId)->get();
//                }


                foreach ($renters as $renter) {

                    if ($remain > 0) {
                        Notification::create([
                            'image' => $this->user->image,
                            'to_user' => $renter->user_id,
                            'hostel_id' => $room->hostel->id,
                            'room_id' => $room->id,
                            'title' => 'Thông báo từ itro.vn ',
                            'payload' => $payload,
                            'user_id' => $this->user->id,
                            'content' => 'Đã đóng ' . number_format($amount, 0, '.', '.') . ' đ tiền ' . $type . ' tháng ' . $notiDate . '. Số tiền còn lại phải đóng là ' . number_format($remain, 0, '.', '.') . 'đ',
                        ]);
                    } else {
                        Notification::create([
                            'image' => $this->user->image,
                            'to_user' => $renter->user_id,
                            'hostel_id' => $room->hostel->id,
                            'room_id' => $room->id,
                            'title' => 'Thông báo xác nhận thu tiền từ itro.vn ',
                            'payload' => $payload,
                            'user_id' => $this->user->id,
                            'content' => 'Đã đóng đủ tiền ' . $type . ' tháng ' . $notiDate . '. Số tiền ' . number_format($moneyInfo->pay, 0, '.', '.') . 'đ'
                        ]);
                    }
                }



            }

            \DB::commit();

            $user = Functions::getCurrentUser();

            $contract = $moneyInfo->contract;

            if($contract) {

                $desc = '{' . $user->name . '} vừa thu {' . number_format($amount, 0, '.', '.') . '}, hóa đơn {'.$moneyInfo->name.'} của khách {'.$contract->name.'} phòng {' . $contract->room->name . '} nhà {' . $contract->hostel->name . '}';
                if ($contract->hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                    $desc = '{' . $user->name . '} vừa thu {' . number_format($amount, 0, '.', '.') . '}, hóa đơn {'.$moneyInfo->name.'} của khách {'.$contract->name.'} giường {' . optional($contract->bed)->name . '} phòng {' . $contract->room->name . '} nhà {' . $contract->hostel->name . '}';
                }
                event(new LogAction([
                    'type' => 'add-payment-collect',
                    'user_id' => optional($user)->id,
                    'object_id' => $collectSpend->id,
                    'hostel_id' => $contract->hostel_id,
                    'room_id' => $contract->room_id,
                    'properties' => $collectSpend->toArray(),
                    'desc' => $desc
                ]));
            }
        } catch (\Exception $exception) {
            \DB::rollBack();

            return response([
                'status' => 1,
                'message' => 'Có lỗi xảy ra'
            ]);
        }

        return response([
            'status' => 1,
            'message' => 'Thanh toán thành công'
        ]);
    }

    /**
     * @api {get} /create-payment-multiple Tạo thanh toán cho nhóm hóa đơn
     * @apiName create-payment-multiple
     * @apiGroup Money
     * @apiDescription Tạo thanh toán cho nhóm hóa đơn
     * @apiParam {String} amount
     * @apiParam {Array} money_info_ids[] Các mã hóa đơn thanh toán
     * @apiParam {String} payer Người thanh toán
     * @apiParam {String} payment_method Phương thức thanh toán. 1 là tiền mặt 2 là chuyển khoản
     * @apiParam {String} date_action d/m/Y Ngày lập phiếu thu
     * @apiParam {String} note Ghi chú
     *
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function createPaymentMultiple(Request $request)
    {
        $moneyInfoIds = $request->input('money_info_ids');
        $amount = $request->input('amount');

        if (empty($moneyInfoIds) || !is_array($moneyInfoIds)) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $moneyInfos = MoneyInfo::query()
            ->whereIn('id', $moneyInfoIds)
            ->orderBy('created_at')
            ->get();
        foreach ($moneyInfos as $moneyInfo) {
            if ($amount <= 0) {
                break;
            }

            $remain = $moneyInfo->remain;
            if ($amount >= $remain) {
                $payAmount = $remain;
            } else {
                $payAmount = $amount;
            }
            request()->request->remove('amount');
            request()->request->add([
                'money_info_id' => $moneyInfo->id,
                'amount' => $payAmount,
            ]);
            $this->createPayment(request());
            $amount = $amount - $remain;
        }

        return response([
            'status' => 1,
            'message' => 'Success'
        ]);
    }

    public function charge(Request $request)
    {
        $data = $request->all();
        $files = $request->file('files');
        $dateAction = $data['date_action'];
        $amount = $data['amount'];

        if (empty(trim($dateAction))) {
            return response([
                'status' => 0,
                'message' => 'Không được để trống ngày thanh toán'
            ]);
        }

        if (empty(trim($amount))) {
            return response([
                'status' => 0,
                'message' => 'Không được để trống số tiền thanh toán'
            ]);
        }

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền không hợp lệ'
            ]);
        }

        $id = $data['id'];
        if (!empty($dateAction)) {
            $dateAction = Carbon::createFromFormat('d/m/Y', $dateAction)->toDateString();

        } else {
            $dateAction = Carbon::now()->toDateString();
        }

        $moneyInfo = MoneyInfo::find($id);

        $remain = 0;

        $payload = json_encode([
            'id' => null,
            'type' => null
        ]);

        $type = 'phòng';
        if ($moneyInfo->type == MoneyInfo::VOUCHER_SERVICE) {
            $type = 'dịch vụ';
        }

        if ($moneyInfo) {
            $userId = $this->user->id;

            $currentRemain = $moneyInfo->remain;

            if ($amount > $currentRemain) {
                return response([
                    'status' => 0,
                    'message' => 'Vui lòng không thu quá số tiền còn lại'
                ]);
            }

            $transaction = Transaction::create([
                'amount' => $amount,
                'hostel_id' => $moneyInfo->hostel_id,
                'room_id' => $moneyInfo->room_id,
                'date_action' => $dateAction,
                'user_id' => $userId,
                'money_info_id' => $moneyInfo->id,
                'type' => CollectSpend::COLLECT
            ]);

            $payload = json_encode([
                'id' => $moneyInfo->id,
                'type' => config('constants.TRANSACTION')
            ]);

            $remain = $moneyInfo->remain - $amount;

            $moneyInfo->pay = $moneyInfo->pay + $amount;
            $moneyInfo->remain = $remain;
            $moneyInfo->save();

            $cp = CollectSpend::create([
                'amount' => $amount,
                'hostel_id' => $moneyInfo->hostel_id,
                'room_id' => $moneyInfo->room_id,
                'payment_method' => CollectSpend::MONEY,
                'date_action' => $dateAction,
                'type' => CollectSpend::COLLECT,
                'name' => $this->user->name,
                'transaction_id' => $transaction->id
            ]);

            if (!empty($files) && is_array($files)) {
                foreach ($files as $key => $file) {
                    $name = time() . $file->getClientOriginalName();
                    $filePath = 'collect-spends/' . $cp->id . '/files/' . str_slug($name);
                    $filePath = $filePath . '.' . $file->getClientOriginalExtension();
                    \Storage::disk('s3')->put($filePath, file_get_contents($file), 'public');
                    CollectSpendFile::create([
                        'collect_spend_id' => $cp->id,
                        'name' => $file->getClientOriginalName(),
                        'file' => 'https://resident.sgp1.digitaloceanspaces.com/' . $filePath
                    ]);
                }
            }
        }

        $room = Room::find($moneyInfo->room_id);

        if ($room) {
            $room->debt = $remain;
            $room->save();

            $notiDate = $moneyInfo->date_action->format('m/Y');

            $renters = RenterRoom::where('room_id', $room->id)->get();


            foreach ($renters as $renter) {
                if ($remain > 0) {
                    Notification::create([
                        'image' => $this->user->image,
                        'to_user' => $renter->user_id,
                        'hostel_id' => $room->hostel->id,
                        'room_id' => $room->id,
                        'title' => 'Thông báo từ itro.vn',
                        'payload' => $payload,
                        'user_id' => $this->user->id,
                        'content' => 'Đã đóng ' . number_format($amount, 0, '.', '.') . ' đ tiền ' . $type . ' tháng ' . $notiDate . '. Số tiền còn lại phải đóng là ' . number_format($remain, 0, '.', '.') . 'đ',
                    ]);
                } else {
                    Notification::create([
                        'image' => $this->user->image,
                        'to_user' => $renter->user_id,
                        'hostel_id' => $room->hostel->id,
                        'room_id' => $room->id,
                        'title' => 'Thông báo từ itro.vn',
                        'payload' => $payload,
                        'user_id' => $this->user->id,
                        'content' => 'Đã đóng đủ tiền ' . $type . ' tháng ' . $notiDate . '. Số tiền ' . number_format($moneyInfo->pay, 0, '.', '.') . 'đ'
                    ]);
                }
            }
        }


        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }

    /**
     * @api {get} /paid-history Lấy lịch sử thanh toán
     * @apiName paid-history
     * @apiGroup Money
     * @apiDescription Api Lấy lịch sử thanh toán
     * @apiParam {String} room_id
     * @apiParam {String} money_info_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function history(Request $request)
    {
        $roomId = $request->input('room_id');
        $moneyInfoId = $request->input('money_info_id');

        $room = Room::find($roomId);

        if ($room) {

            $items = Transaction::select(\DB::raw('transactions.*, collect_spends.payer, collect_spends.payment_method'))->where('transactions.type', CollectSpend::COLLECT)
                ->leftjoin('collect_spends', 'transactions.id', '=', 'collect_spends.transaction_id')
                ->where('transactions.money_info_id', $moneyInfoId)
                ->orderBy('transactions.id', 'desc')
                ->get();

            foreach ($items as $item) {
                $moneyInfo = MoneyInfo::find($moneyInfoId);
                if ($moneyInfo) {
                    $contractId = $moneyInfo->contract_id;
                    $contract = Contract::find($contractId);
                    if ($contract) {
                        $item->contract_status = $contract->status;
                    }
                }
            }

            return response([
                'status' => 1,
                'data' => $items
            ]);
        }

        return response([
            'status' => '0',
            'message' => 'Dữ liệu không hợp lệ'
        ]);
    }


    /**
     * @api {get} /paid-history-2 Lấy lịch sử thanh toán
     * @apiName paid-history-2
     * @apiGroup Money
     * @apiDescription Api Lấy lịch sử thanh toán
     * @apiParam {String} room_id
     * @apiParam {String} money_info_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function history2(Request $request)
    {
        $roomId = $request->input('room_id');
        $moneyInfoId = $request->input('money_info_id');

        $room = Room::find($roomId);
        if (!$room) {
            return response([
                'status' => '0',
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $items = CollectSpend::query()
            ->with('user')
            ->with('hostel')
            ->with('moneyInfo')
            ->with('moneyInfo.contract')
            ->with('typeCollect')
            ->where('type', CollectSpend::COLLECT)
            ->when(!empty($moneyInfoId), function ($q) use ($moneyInfoId) {
                $q->where('money_info_id', $moneyInfoId);
            })
            ->where('room_id', $roomId)
            ->orderBy('id', 'desc')
            ->get();

        foreach ($items as $item) {
            $moneyInfo = $item->moneyInfo;
            if ($moneyInfo) {
                $contract = $moneyInfo->contract;
                if ($contract) {
                    $item->contract_status = $contract->status;
                }
            }
        }

        return response([
            'status' => 1,
            'data' => $items
        ]);


    }

    /**
     * @api {get} /list Lấy danh sách các hóa đơn
     * @apiName list
     * @apiGroup Money
     * @apiDescription Api Lấy danh sách các hóa đơn
     * @apiParam {String} type
     * @apiParam {String} start_date
     * @apiParam {String} end_date
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function listItems(Request $request)
    {
        $type = $request->input('type');
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $hostelId = $request->input('hostel_id');
        $roomId = $request->input('room_id');
        $contractId = $request->input('contract_id');
        $items = MoneyInfo::query()->select(\DB::raw('MONTH(date_action) as month, YEAR(date_action) as year'));

        if (!empty($startDate)) {
            $startDateAction = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->startOfMonth()->toDateString();
            $items = $items->where('money_infos.date_action', '>=', $startDateAction);

        }

        if (!empty($endDate)) {
            $endDateAction = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->endOfMonth()->toDateString();
            $items = $items->where('money_infos.date_action', '<=', $endDateAction);
        }
        $retVal = [];

        $historiesItems = MoneyInfo::query()->selectRaw('*, remain as remain')->with('details');

        if ($this->user) {
            if ($this->user->type == User::OWNER) {
                $hostels = Hostel::query()->where('owner_id', $this->user->id)->pluck('id')->toArray();
                $historiesItems = $historiesItems->whereIn('hostel_id', $hostels);
            } else if ($this->user->type == User::STAFF) {
                $hostels = Functions::getHostelArrStaffApi($this->user);
                $historiesItems = $historiesItems->whereIn('hostel_id', $hostels);
            }
        }

        if (!empty($hostelId)) {
            $historiesItems = $historiesItems->where('hostel_id', $hostelId);
            $items = $items->where('hostel_id', $hostelId);
        }


        if (!empty($roomId)) {
            $historiesItems = $historiesItems->where('room_id', $roomId);
            $items = $items->where('room_id', $roomId);
        }
        if (!empty($contractId)) {
            $historiesItems = $historiesItems->where('contract_id', $contractId);
            $items = $items->where('contract_id', $contractId);
        }


        $items = $items->groupBy(\DB::raw('month, year'))->orderBy('date_action', 'desc')->get();
        if (!empty($type)) {
            if ($type == 'not-pay') {
                $historiesItems = $historiesItems->where('remain', '!=', 0);
            } else if ($type == 'full-pay') {
                $historiesItems = $historiesItems->where('remain', '=', 0);
            }
        }


        $historiesItems = $historiesItems
            ->with('hostel')
            ->with('room')
            ->with('contract');

        foreach ($items as $item) {
            $month = $item->month;
            $year = $item->year;

            $startDate = Carbon::createFromFormat('d/m/Y', '01/' . $month . '/' . $year)->startOfMonth()->startOfDay()->toDateString();
            $endDate = Carbon::createFromFormat('d/m/Y', '01/' . $month . '/' . $year)->endOfMonth()->endOfDay()->toDateString();


            $check = clone $historiesItems;
            $histories = clone $historiesItems;
            $check = $check->whereBetween('date_action', [$startDate, $endDate])->count();

            if ($check > 0) {
                $histories = $histories->whereBetween('date_action', [$startDate, $endDate])->get();
                //dd($histories);
                foreach ($histories as $history) {
                    $hostel = $history->hostel;
                    $history->hostel_type_rent = optional($hostel)->type_rent;


                    if (in_array($history->type, [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])) {
                        $detail = $history->details->first();
                        if ($detail) {
                            $startDateMoneyInfo = Carbon::createFromFormat('Y-m-d', $detail->start_date);
                            $endDateMoneyInfo = Carbon::createFromFormat('Y-m-d', $detail->end_date);
                            $history->start_date = $startDateMoneyInfo->format('d/m/Y');
                            $history->end_date = $endDateMoneyInfo->format('d/m/Y');
                        }
                    }

                    if ($hostel) {
                        $history->hostel_name = $hostel->name;
                    } else {
                        $history->hostel_name = '';
                    }

                    if ($history->room_id) {

                        if ($hostel) {
                            $contract = $history->contract;
                            if ($contract) {

                                $users = RenterRoom::query()->withTrashed()->selectRaw('users.*')->join('users', 'users.id', '=', 'renter_rooms.user_id')
                                    ->where('renter_rooms.contract_id', $contract->id)->get();

                                $userArr = [];
                                foreach ($users as $user) {
                                    $userArr[] = [
                                        'id' => $user->id,
                                        'name' => $user->name,
                                        'phone' => $user->phone,
                                        'email' => $user->email
                                    ];
                                }

                                $history->users = $userArr;

                            }


                            $room = $history->room;
                            if ($room) {
                                $history->room_name = $room->name;
                            } else {
                                $history->room_name = '';
                            }
                        } else {
                            $history->hostel_name = '';
                        }
                    }
                    if ($history->contract->bed_id) {
                        $bed = RoomBed::find($history->contract->bed_id);
                        if ($bed) {
                            $history->bed = $bed;
                            $history->bed_name = $bed->name;
                        }

                    }
                    unset($history->room);
                    unset($history->hostel);
                }
                $itemVal = [
                    'time' => 'Tháng ' . $month . '/' . $year,
                    'histories' => collect($histories)->sortBy('room_name')->values()->all(),
                    // 'histories' => $histories
                ];

                $retVal[] = $itemVal;
            }
        }

        return response([
            'status' => 1,
            'data' => $retVal
        ]);
    }

    /**
     * @api {get} /list-before Lấy danh sách các hóa đơn tiền nhà tháng này, dịch vụ tháng trc
     * @apiName list-before
     * @apiGroup Money
     * @apiDescription Lấy danh sách các hóa đơn tiền nhà tháng này, dịch vụ tháng trc
     * @apiParam {String} type
     * @apiParam {String} start_date
     * @apiParam {String} end_date
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function listBeforeItems(Request $request)
    {
        $type = $request->input('type');
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $hostelId = $request->input('hostel_id');
        $roomId = $request->input('room_id');
        $contractId = $request->input('contract_id');


        $owner = $this->user;
        if ($this->user->type == User::STAFF) {
            $owner = $this->user->owner;
        }
        $startDateAction = null;
        $endDateAction = null;

        $historiesItems = MoneyInfo::query()
            ->selectRaw('*, remain as remain')
            ->with('details');

        if (!empty($startDate)) {
            $startDateAction = Carbon::createFromFormat('d/m/Y', '01/' . $startDate);
        }
        if (!empty($endDate)) {
            $endDateAction = Carbon::createFromFormat('d/m/Y', '01/' . $endDate);
        }

        $retVal = [];

        if ($this->user) {
            if ($this->user->type == User::OWNER) {
                $hostels = Hostel::query()->where('owner_id', $this->user->id)->pluck('id')->toArray();
                $historiesItems = $historiesItems->whereIn('hostel_id', $hostels);

            } else {
                $hostels = Functions::getHostelArrStaffApi($this->user);
                $historiesItems = $historiesItems->whereIn('hostel_id', $hostels);

            }
        }

        if (!empty($hostelId)) {
            $historiesItems = $historiesItems->where('hostel_id', $hostelId);

        }


        if (!empty($roomId)) {
            $historiesItems = $historiesItems->where('room_id', $roomId);

        }

        if (!empty($contractId)) {
            $historiesItems = $historiesItems->where('contract_id', $contractId);
        }


        if (!empty($type)) {
            if ($type == 'not-pay') {
                $historiesItems = $historiesItems->where('remain', '<>', 0);
            } else if ($type == 'full-pay') {
                $historiesItems = $historiesItems->where('remain', 0);
            }
        }


        $historiesItems = $historiesItems
            ->with('hostel')
            ->with('room')
            ->with('contract');

        $items = [];
        for ($i = $startDateAction->copy(); $i->lessThanOrEqualTo($endDateAction); $i->addMonth()) {
            $items[] = $i->copy();
        }

        foreach ($items as $item) {
            $month = $item->copy()->month;
            $year = $item->copy()->year;

            $startDate = Carbon::createFromFormat('d/m/Y', '01/' . $month . '/' . $year);
            $endDate = Carbon::createFromFormat('d/m/Y', '01/' . $month . '/' . $year);

            $historyMoneyInfos = clone $historiesItems;
            $historyServices = clone $historiesItems;

            $historyMoneyInfos = $historyMoneyInfos
                ->whereIn('type', [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])
                ->whereBetween('date_action', [
                    $startDate->copy()->startOfMonth()->startOfDay()->toDateString(),
                    $endDate->copy()->endOfMonth()->endOfDay()->toDateString()
                ])
                ->get();
            $historyServices = $historyServices
                ->where('type', MoneyInfo::VOUCHER_SERVICE)
                ->whereBetween('date_action', [
                    $startDate->copy()->startOfMonth()->subMonth()->startOfMonth()->startOfDay()->toDateString(),
                    $endDate->copy()->startOfMonth()->subMonth()->endOfMonth()->endOfDay()->toDateString()
                ])
                ->get();

            //dd($historyServices->pluck('note')->toArray());

            $histories = $historyMoneyInfos->merge($historyServices);
            //dd($histories);
            foreach ($histories as $history) {
                $hostel = $history->hostel;

                if (in_array($history->type, [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])) {
                    $detail = $history->details->first();
                    if ($detail) {
                        $startDateMoneyInfo = Carbon::createFromFormat('Y-m-d', $detail->start_date);
                        $endDateMoneyInfo = Carbon::createFromFormat('Y-m-d', $detail->end_date);
                        $history->start_date = $startDateMoneyInfo->format('d/m/Y');
                        $history->end_date = $endDateMoneyInfo->format('d/m/Y');
                    }
                }

                if ($hostel) {
                    $history->hostel_name = $hostel->name;
                } else {
                    $history->hostel_name = '';
                }

                if ($history->room_id) {

                    if ($hostel) {
                        $contract = $history->contract;
                        if ($contract) {

                            $users = RenterRoom::query()->withTrashed()->selectRaw('users.*')->join('users', 'users.id', '=', 'renter_rooms.user_id')
                                ->where('renter_rooms.contract_id', $contract->id)->get();

                            $userArr = [];
                            foreach ($users as $user) {
                                $userArr[] = [
                                    'id' => $user->id,
                                    'name' => $user->name,
                                    'phone' => $user->phone,
                                    'email' => $user->email
                                ];
                            }

                            $history->users = $userArr;

                        }


                        $room = $history->room;
                        if ($room) {
                            $history->room_name = $room->name;
                        } else {
                            $history->room_name = '';
                        }
                    } else {
                        $history->hostel_name = '';
                    }
                }
                if ($history->contract->bed_id) {
                    $bed = RoomBed::find($history->contract->bed_id);
                    if ($bed) {
                        $history->bed = $bed;
                        $history->bed_name = $bed->name;
                    }

                }
                unset($history->room);
                unset($history->hostel);
            }


            $itemVal = [
                'time' => 'Tháng ' . $month . '/' . $year,
                'histories' => $histories
            ];

            $retVal[] = $itemVal;

        }

        return response([
            'status' => 1,
            'data' => $retVal
        ]);
    }


    public function getMoneyByAttribute(Request $request)
    {
        $items = CollectSpend::query()->selectRaw('money_infos.*, contracts.code as contract_code, contracts.reference')
            ->leftJoin('money_infos', 'collect_spends.money_info_id', '=', 'money_infos.id')
            ->leftJoin('contracts', 'contracts.id', '=', 'money_infos.contract_id')
            ->orderBy('id', 'desc');

        if ($this->user) {
            if ($this->user->type == User::OWNER) {
                $hostels = Hostel::where('owner_id', $this->user->id)->pluck('id')->toArray();
                $items = $items->whereIn('hostel_id', $hostels);
            }
        }

        $startTime = $request->input('start_time');
        $endTime = $request->input('end_time');
        $timeRange = $request->input('time_range');

        if (!empty($timeRange)) {

        }

        return Datatables::of($items)
            ->editColumn('type', function ($item) {
                return $item->type_text;
            })
            ->editColumn('amount', function ($item) {
                return number_format($item->amount, 0, '.', '.');
            })
            ->editColumn('date_action', function ($item) {
                return $item->date_action->format('d/m/Y');
            })
            ->editColumn('created_at', function ($item) {
                return $item->created_at->format('d/m/Y');
            })
            ->addColumn('action', function ($item) {


            })->make(true);
    }

    public function createMoneyChange(Request $request)
    {

    }

    public function calculateFee($hostelId, $rooms, $dateAction)
    {
        if (empty($dateAction)) {
            $startDate = Carbon::now()->startOfMonth()->toDateString();
            $endDate = Carbon::now()->endOfMonth()->toDateString();
        } else {
            $startDate = Carbon::createFromFormat('d/m/Y', '01/'.$dateAction)->startOfMonth()->toDateString();
            $endDate = Carbon::createFromFormat('d/m/Y', '01/'.$dateAction)->endOfMonth()->toDateString();
        }

        foreach ($rooms as $room) {

            $moneyInfo = MoneyInfo::where('room_id', $room->id)->where('date_action', '>=', $startDate)->where('date_action', '<=', $endDate)->first();

            $amount = Functions::calculateAmountMonthForRoom($room, $dateAction);
            if ($moneyInfo) {
                $payBefore = Transaction::query()->where('room_id', $room->id)
                    ->where('date_action', '>=', $startDate)
                    ->where('date_action', '<=', $endDate)
                    ->sum('amount');

                $pay = $payBefore + $amount['pay'];

                $moneyInfo->update([
                    'amount' => $amount['amount'],
                    'pay' => $pay,
                    'remain' => $amount['amount'] - $pay
                ]);

                $moneyInfo->save();

                if ($room) {
                    $room->debt = $amount['amount'] - $pay;
                    $room->save();
                }
            } else {


                $moneyInfo = MoneyInfo::create([
                    'hostel_id' => $hostelId,
                    'room_id' => $room->id,
                    'amount' => $amount['amount'],
                    'pay' => $amount['pay'],
                    'remain' => $amount['amount'] - $amount['pay'],
                    'date_action' => Carbon::createFromFormat('d/m/Y', '01/'.$dateAction)->toDateString(),
                ]);

                if ($room) {
                    $room->debt = $amount['amount'] - $amount['pay'];
                    $room->save();
                }

            }

            MoneyDetail::where('money_info_id', $moneyInfo->id)->delete();
            $fees = RoomFee::where('room_id', $room->id)->get();

            $extras = Extra::where('room_id', $room->id)
                ->where('date_action', '>=', $startDate)
                ->where('date_action', '<=', $endDate)->get();

            $ew = ElectricWater::where('room_id', $room->id)->where('date_action', '>=', $startDate)->where('date_action', '<=', $endDate)->first();

            $hostel = $room->hostel;

            MoneyDetail::create([
                'room_id' => $room->id,
                'hostel_id' => $hostelId,
                'name' => 'Tiền phòng',
                'value' => $room->price,
                'money_info_id' => $moneyInfo->id,
                'qty' => 1,
                'amount' => $room->price,
                'is_electric' => true,
            ]);

            if ($ew) {

                $ewPrice = Functions::getEwRoom($room);
                $deltaWater = $ew->delta_water;
                $deltaElectric = $ew->delta_electric;
                $ewAmountElectric = $deltaElectric * $ewPrice['electric'];
                $ewAmountWater = $deltaWater * $ewPrice['water'];

                MoneyDetail::create([
                    'room_id' => $room->id,
                    'hostel_id' => $hostelId,
                    'name' => 'Điện',
                    'value' => $ewPrice['electric'],
                    'money_info_id' => $moneyInfo->id,
                    'qty' => json_encode([
                        'start' => $ew->start_electric,
                        'end' => $ew->end_electric,
                        'item_id' => $ew->id
                    ]),
                    'amount' => $ewAmountElectric,
                    'is_electric' => true,

                ]);

                MoneyDetail::create([
                    'room_id' => $room->id,
                    'hostel_id' => $hostelId,
                    'name' => 'Nước',
                    'value' => $ewPrice['water'],
                    'money_info_id' => $moneyInfo->id,
                    'qty' => json_encode([
                        'start' => $ew->start_water,
                        'end' => $ew->end_water,
                        'item_id' => $ew->id
                    ]),
                    'amount' => $ewAmountWater,
                    'is_water' => true
                ]);
            }

            foreach ($fees as $fee) {
                MoneyDetail::create([
                    'room_id' => $room->id,
                    'hostel_id' => $hostelId,
                    'name' => $fee->name,
                    'value' => $fee->fee,
                    'amount' => $fee->fee,
                    'qty' => 1,
                    'money_info_id' => $moneyInfo->id
                ]);
            }

            foreach ($extras as $extra) {
                MoneyDetail::create([
                    'room_id' => $room->id,
                    'hostel_id' => $hostelId,
                    'name' => $extra->name,
                    'value' => $extra->amount,
                    'amount' => $extra->amount,
                    'qty' => 1,
                    'money_info_id' => $moneyInfo->id
                ]);
            }

        }
    }

    public function detailSpend(Request $request)
    {
        $id = $request->input('id');

        $item = Transaction::find($id);

        if ($item) {
            return response([
                'status' => 1,
                'message' => 'Thành công',
                'data' => $item
            ]);
        }

        return response([
            'status' => 0,
            'message' => 'Dữ liệu không hợp lệ'
        ]);
    }

    public function update(Request $request)
    {
        $fees = $request->input('fees');
        $fees = json_decode($fees, true);
        $sum = 0;
        $infoId = null;

        DB::beginTransaction();
        try {
            if (!empty($fees)) {
                if (is_array($fees)) {
                    foreach ($fees as $fee) {
                        $id = $fee['id'];
                        $item = MoneyDetail::find($id);
                        $qty = 1;
                        $amount = 0;
                        if ($item) {

                            $infoId = $item->money_info_id;

                            $itemId = $fee['item_id'];

                            if ($itemId > 0) {
                                $ew = ElectricWater::find($itemId);

                                $qty = $fee['qty'];

                                if ($fee['type'] == 'electric') {

                                    $lastElectric = $qty;

                                    $currQty = json_decode($item->qty, true);
                                    $currQty['end'] = $lastElectric;
                                    $startElectric = $currQty['start'];
                                    $amount = ($lastElectric - $startElectric) * $item->hostel->electric_price;

                                    $ew->end_electric = $lastElectric;
                                    $ew->delta_electric = $lastElectric - $ew->start_electric;

                                } else if ($fee['type'] == 'water') {
                                    $lastWater = $qty;
                                    $currQty = json_decode($item->qty, true);
                                    $currQty['end'] = $lastWater;

                                    $startWater = $currQty['start'];
                                    $amount = ($lastWater - $startWater) * $item->hostel->water_price;

                                    $ew->end_water = $lastWater;
                                    $ew->delta_water = $lastWater - $ew->start_water;
                                }

                                $qty = json_encode($currQty);

                                $ew->save();
                            } else {
                                $amount = $item->value * $qty;
                            }

                            $item->qty = $qty;
                            $item->amount = $amount;
                            $item->save();
                        }

                    }
                }
            }

            $info = MoneyInfo::find($infoId);
            if ($info) {
                $info->amount = $sum;
                $info->remain = $sum - $info->pay;
                $info->save();

                $room = Room::find($info->room_id);
                if ($room) {
                    $room->debt = $sum - $info->pay;
                    $room->save();
                }
            }

            DB::commit();

        } catch (\Exception $ex) {
            DB::rollBack();

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }


        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }

    public function detail(Request $request)
    {
        $id = $request->input('id');
        $item = MoneyInfo::find($id);
        if (!$item) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }
        $details = MoneyDetail::where('money_info_id', $id)->get();
        $room = $item->room;
        $dateAction = $item->date_action->format('m/Y');
        $pay = Functions::calculateAmountMonthForRoom($room, $dateAction)['pay'];

        $retVal = [];
        $mainVal = [];

        $sum = 0;
        foreach ($details as $detail) {

            $qty = $detail->qty;
            $type = 'other';
            $itemId = '-1';

            $data = json_decode($qty, true);

            if (is_array($data)) {
                if ($detail->is_electriwc) {
                    $type = 'electric';
                } else {
                    $type = 'water';
                }

                if (!empty($data['item_id'])) {
                    $itemId = $data['item_id'];
                }

                $qty = $data['end'];
            }

            $itemArr = [
                'id' => $detail->id,
                'item_id' => $itemId,
                'name' => $detail->name,
                'value' => $detail->value,
                'qty' => $qty,
                'amount' => $detail->amount,
                'type' => $type
            ];

            $sum += $detail->amount;

            $mainVal[] = $itemArr;
        }

        $retVal['sum'] = $sum;
        $retVal['paid'] = $pay;
        $retVal['remain'] = $sum - $pay;
        $retVal['fees'] = $mainVal;
        $retVal['info_id'] = $id;
        if ($item->room) {
            $retVal['room_name'] = $item->room->name;
        }

        $item['date_action'] = $dateAction;

        return response([
            'status' => 1,
            'data' => $retVal
        ]);
    }


    public function calculateMoneyChange(Request $request)
    {
        $dateAction = $request->input('date_action');
        $hostels = $request->input('hostels');
        $rooms = $request->input('rooms');

        if (empty($dateAction)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống date_action'
            ]);
        }

        try {
            \DB::beginTransaction();

            if (empty($hostels)) {
                $hostels = Hostel::all();
                foreach ($hostels as $hostel) {
                    $rooms = Room::where('hostel_id', $hostel->id)->get();

                    $this->calculateFee($hostel->id, $rooms, $dateAction);
                }
            }

            if (!empty($hostels)) {

                $hostels = json_decode($hostels, true);
                if (!empty($rooms)) {
                    $rooms = json_decode($rooms, true);
                    $rooms = Room::whereIn('id', $rooms)->get();
                } else {
                    $rooms = Room::whereIn('hostel_id', $hostels)->get();
                }

                if (is_array($hostels)) {
                    foreach ($hostels as $hostel) {
                        $this->calculateFee($hostel, $rooms, $dateAction);
                    }
                }
            }

            \DB::commit();

            return response([
                'status' => 1,
                'message' => 'Success'
            ]);
        } catch (\Exception $ex) {
            \DB::rollBack();

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau',
                'error' => $ex->getMessage() . '|' . $ex->getLine()
            ]);
        }
    }

    public function fullCharge(Request $request)
    {
        $roomId = $request->input('room_id');
        $room = Room::find($roomId);
        if (!$room) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $moneyInfos = MoneyInfo::where('remain', '>', 0)->where('room_id', $roomId)
            ->get();

        foreach ($moneyInfos as $moneyInfo) {
            if ($moneyInfo) {
                $userId = $this->user->id;
                $amount = $moneyInfo->remain;

                Transaction::create([
                    'amount' => $amount,
                    'hostel_id' => $moneyInfo->hostel_id,
                    'room_id' => $moneyInfo->room_id,
                    'date_action' => Carbon::now()->toDateString(),
                    'user_id' => $userId
                ]);

                $remain = $moneyInfo->remain - $amount;

                $moneyInfo->pay = $moneyInfo->pay + $amount;
                $moneyInfo->remain = $remain;
                $moneyInfo->save();

                $type = 'phòng';
                if ($moneyInfo->type == MoneyInfo::VOUCHER_SERVICE) {
                    $type = 'dịch vụ';
                }

            }

            $room = Room::find($moneyInfo->room_id);

            if ($room) {
                $room->debt = $remain;
                $room->save();

                $notiDate = $moneyInfo->date_action->format('m/Y');

                $renters = RenterRoom::where('room_id', $room->id)->get();

                foreach ($renters as $renter) {
                    if ($remain > 0) {
                        Notification::create([
                            'image' => $this->user->image,
                            'to_user' => $renter->user_id,
                            'hostel_id' => $room->hostel->id,
                            'room_id' => $room->id,
                            'title' => 'Thông báo từ itro.vn',
                            'user_id' => $this->user->id,
                            'content' => 'Đã đóng ' . number_format($amount, 0, '.', '.') . ' đ tiền ' . $type . ' tháng ' . $notiDate . '. Số tiền còn lại phải đóng là ' . number_format($remain, 0, '.', '.') . 'đ',
                        ]);
                    } else {
                        Notification::create([
                            'image' => $this->user->image,
                            'to_user' => $renter->user_id,
                            'hostel_id' => $room->hostel->id,
                            'room_id' => $room->id,
                            'title' => 'Thông báo từ itro.vn',
                            'user_id' => $this->user->id,
                            'content' => 'Xác nhận đã thu đủ ' . number_format($amount, 0, '.', '.') . 'đ còn nợ'
                        ]);
                    }
                }
            }
        }

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);

    }

    /**
     * @api {get} /edit-payment Cập nhật payment
     * @apiName edit-payment
     * @apiGroup Money
     * @apiDescription Api Cập nhật payment
     * @apiParam {String} transaction_id
     * @apiParam {String} amount
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */


    public function updateTransactionCollect(Request $request)
    {
        $transactionId = $request->input('transaction_id');
        $amount = Functions::filterInputNumber($request->input('amount'));

        $transaction = Transaction::find($transactionId);

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền phải là số'
            ]);
        }

        if (!$transaction) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        try {

            \DB::beginTransaction();

            $transaction->amount = $amount;
            $transaction->save();

            $collectSpend = CollectSpend::where('transaction_id', $transaction->id)->first();
            if ($collectSpend) {
                $collectSpend->amount = $amount;
                $collectSpend->save();
            }

            $paid = Transaction::where('money_info_id', $transaction->money_info_id)->sum('amount');
            $moneyInfo = MoneyInfo::find($transaction->money_info_id);
            if ($moneyInfo) {
                $moneyInfo->pay = $paid;
                $moneyInfo->remain = $moneyInfo->amount - $moneyInfo->discount - $paid;
                $moneyInfo->save();
            }

            \DB::commit();

        } catch (\Exception $exception) {
            \DB::rollBack();

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }

    /**
     * @api {get} /detail-money-info Chi tiết hóa đơn
     * @apiName detail-money-info
     * @apiGroup Money
     * @apiDescription Api Chi tiết hóa đơn
     * @apiParam {String} money_info_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function detailMoneyInfo(Request $request)
    {
        $moneyInfoId = $request->input('money_info_id');
        $moneyInfo = MoneyInfo::find($moneyInfoId);
        if (!$moneyInfo) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $details = MoneyDetail::where('money_info_id', $moneyInfoId)->get();

        $retVal = [];

        $sum = $moneyInfo->amount;
        $pay = $moneyInfo->pay;
        $remain = $moneyInfo->remain;

        foreach ($details as $detail) {


            $retVal['items'][] = [
                'id' => $detail->hostel_fee_id,
                'name' => $detail->name,
                'price' => (in_array(optional($detail->hostelFee)->type, [
                    HostelFee::ELECTRIC,
                    HostelFee::WATER
                ])) ? -1 : $detail->value,
                'start_index' => (int)$detail->start_index,
                'end_index' => (int)$detail->end_index,
                'qty' => strval($detail->qty_text_2),
                'amount' => !empty($detail->sum_amount) ? $detail->sum_amount : $detail->amount,
                'type' => !empty($detail->hostelFee) ? $detail->hostelFee->type : HostelFee::OTHER

            ];
        }

        $userArr = [];
        $contract = Contract::find($moneyInfo->contract_id);
        if ($contract) {
            $users = RenterRoom::selectRaw('users.*')->join('users', 'users.id', '=', 'renter_rooms.user_id')
                ->withTrashed()
                ->where('renter_rooms.contract_id', $contract->id)->get();

            foreach ($users as $user) {
                $userArr[] = [
                    'id' => $user->id,
                    'name' => $user->name,
                    'phone' => $user->phone,
                    'email' => $user->email
                ];
            }

        }
        $retVal['name'] = $moneyInfo->name;
        $retVal['config_note'] = Functions::getConfigNote($moneyInfo->hostel);
        $retVal['hostel_name'] = $moneyInfo->hostel ? $moneyInfo->hostel->name : null;
        $retVal['hostel_id'] = $moneyInfo->hostel ? $moneyInfo->hostel->id : null;
        $retVal['hostel_type_rent'] = $moneyInfo->hostel ? $moneyInfo->hostel->type_rent : null;
        $retVal['room_name'] = $moneyInfo->room ? $moneyInfo->room->name : null;
        $retVal['id'] = $moneyInfo->id;
        $retVal['room_id'] = $moneyInfo->room_id;
        $retVal['user'] = $moneyInfo->contract ? $moneyInfo->contract->name : null;
        $retVal['amount'] = $sum;
        $retVal['pay'] = $pay;
        $retVal['remain'] = $remain;
        $retVal['discount'] = $moneyInfo->discount;
        $retVal['users'] = $userArr;
        $retVal['date_action'] = $moneyInfo->date_action->format('m/Y');
        $retVal['type'] = $moneyInfo->type;
        $retVal['note'] = $moneyInfo->note;

        if (in_array($moneyInfo->type, [MoneyInfo::VOUCHER_ROOM_PRICE, MoneyInfo::VOUCHER_CONTRACT])) {
            $detailItem = $details->first();
            if ($detailItem) {
                $retVal['start_date'] = Carbon::createFromFormat('Y-m-d', $detailItem->start_date)->format('d/m/Y');
                $retVal['end_date'] = Carbon::createFromFormat('Y-m-d', $detailItem->end_date)->format('d/m/Y');
            }
        }

        if ($contract) {
            $retVal['contract'] = [
                'id' => $contract->id,
                'name' => $contract->name
            ];
            if ($contract->bed) {
                $retVal['bed'] = [
                    'id' => $contract->bed->id,
                    'name' => $contract->bed->name
                ];
            }
        }


        return response([
            'status' => 1,
            'data' => $retVal
        ]);
    }

    /**
     * @api {get} /detail-money-info-month Chi tiết hóa đơn theo tháng
     * @apiName detail-money-info-month
     * @apiGroup Money
     * @apiDescription Api Chi tiết hóa đơn theo tháng
     * @apiParam {String} money_info_id
     * @apiParam {String} contract_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function detailMoneyInfoMonth(Request $request)
    {
        $id = $request->input('money_info_id');
        $contractId = $request->input('contract_id');

        $item = MoneyInfo::find($id);

        $contract = Contract::find($contractId);
        if (!$contract) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if (!$item) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $startDate = $item->date_action->startOfMonth()->startOfDay();
        $endDate = $item->date_action->endOfMonth()->endOfDay();

        $items = MoneyInfo::whereBetween('date_action', [$startDate, $endDate])
            ->where('contract_id', $contractId);

        $sum = clone $items;
        $pay = clone $items;
        $remain = clone $items;
        $discount = clone $items;

        $ids = $items->get()->pluck('id')->toArray();
        $details = MoneyDetail::whereIn('money_info_id', $ids)->get();

        $retVal = [];
        $userArr = [];

        $sum = $sum->sum('amount');
        $pay = $pay->sum('pay');
        $remain = $remain->sum('remain');
        $discount = $discount->sum('discount');

        foreach ($details as $detail) {
            $retVal['items'][] = [
                'id' => $detail->hostel_fee_id,
                'name' => $detail->name,
                'price' => (in_array(optional($detail->hostelFee)->type, [
                    HostelFee::ELECTRIC,
                    HostelFee::WATER
                ])) ? -1 : $detail->value,
                'start_index' => intval($detail->start_index),
                'end_index' => intval($detail->end_index),
                'qty' => intval($detail->qty_text_2),
                'amount' => !empty($detail->sum_amount) ? $detail->sum_amount : $detail->amount,
                'type' => !empty($detail->hostelFee) ? $detail->hostelFee->type : HostelFee::OTHER

            ];
        }
        if ($contract) {
            $users = RenterRoom::query()->selectRaw('users.*')->join('users', 'users.id', '=', 'renter_rooms.user_id')
                ->where('renter_rooms.contract_id', $contract->id)->get();

            foreach ($users as $user) {
                $userArr[] = [
                    'id' => $user->id,
                    'name' => $user->name,
                    'phone' => $user->phone,
                    'email' => $user->email
                ];
            }

        }

        $retVal['name'] = 'Hoá đơn thu tiền tháng ' . $item->date_action->format('m/Y');
        $retVal['config_note'] = Functions::getConfigNote($contract->hostel);
        $retVal['hostel_name'] = $contract->hostel ? $contract->hostel->name : null;
        $retVal['room_name'] = $contract->room ? $contract->room->name : null;
        $retVal['room_id'] = $contract->room_id;
        $retVal['user'] = $contract->name;
        $retVal['amount'] = intval($sum);
        $retVal['pay'] = intval($pay);
        $retVal['remain'] = intval($remain);
        $retVal['discount'] = intval($discount);
        $retVal['users'] = $userArr;
        $retVal['ids'] = $ids;
        $retVal['contract'] = [
            'id' => $contract->id,
            'name' => $contract->name
        ];

        if ($contract->bed) {
            $retVal['bed'] = [
                'id' => $contract->bed->id,
                'name' => $contract->bed->name
            ];
        }


        return response([
            'status' => 1,
            'data' => $retVal
        ]);
    }

    /**
     * @api {get} /detail-money-info-room-service Chi tiết hóa đơn tiền nhà và dịch vụ
     * @apiName detail-money-info-room-service
     * @apiGroup Money
     * @apiDescription Api CChi tiết hóa đơn tiền nhà và dịch vụ
     * @apiParam {String} month Dạng m/Y
     * @apiParam {String} contract_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function detailMoneyInfoRoomAndService(Request $request)
    {
        $month = $request->input('month');
        $contractId = $request->input('contract_id');
        if (empty($month)) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $month = '01/' . $month;

        $contract = Contract::find($contractId);

        if (!$contract) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }


        $dateCarbon = Carbon::createFromFormat('d/m/Y', $month);

        $items = MoneyInfo::query()
            ->where(function ($q) use ($dateCarbon) {
                $q->orWhere(function ($q2) use ($dateCarbon) {
                    $q2->where('type', MoneyInfo::VOUCHER_SERVICE)
                        ->whereBetween('date_action', [
                            $dateCarbon->copy()->subMonth()->startOfMonth()->startOfDay(),
                            $dateCarbon->copy()->subMonth()->endOfMonth()->endOfDay()
                        ]);
                });
                $q->orWhere(function ($q2) use ($dateCarbon) {
                    $q2->whereIn('type', [MoneyInfo::VOUCHER_ROOM_PRICE, MoneyInfo::VOUCHER_CONTRACT])
                        ->whereBetween('date_action', [
                            $dateCarbon->copy()->startOfMonth()->startOfDay(),
                            $dateCarbon->copy()->endOfMonth()->endOfDay()
                        ]);
                });
            })
            ->where('contract_id', $contractId);

        $sum = clone $items;
        $pay = clone $items;
        $remain = clone $items;
        $discount = clone $items;

        $ids = $items->get()->pluck('id')->toArray();
        $details = MoneyDetail::whereIn('money_info_id', $ids)->get();

        $retVal = [];
        $userArr = [];

        $sum = $sum->sum('amount');
        $pay = $pay->sum('pay');
        $remain = $remain->sum('remain');
        $discount = $discount->sum('discount');

        foreach ($details as $detail) {
            $retVal['items'][] = [
                'id' => $detail->hostel_fee_id,
                'name' => $detail->name,
                'price' => (in_array(optional($detail->hostelFee)->type, [
                    HostelFee::ELECTRIC,
                    HostelFee::WATER
                ])) ? -1 : $detail->value,
                'start_index' => intval($detail->start_index),
                'end_index' => intval($detail->end_index),
                'qty' => intval($detail->qty_text_2),
                'amount' => !empty($detail->sum_amount) ? $detail->sum_amount : $detail->amount,
                'type' => !empty($detail->hostelFee) ? $detail->hostelFee->type : HostelFee::OTHER,


            ];
        }

        $users = RenterRoom::query()->selectRaw('users.*')->join('users', 'users.id', '=', 'renter_rooms.user_id')
            ->where('renter_rooms.contract_id', $contract->id)->get();

        foreach ($users as $user) {
            $userArr[] = [
                'id' => $user->id,
                'name' => $user->name,
                'phone' => $user->phone,
                'email' => $user->email
            ];
        }


        $retVal['name'] = 'Hoá đơn thu tiền tháng ' . $dateCarbon->copy()->format('m/Y');
        $retVal['config_note'] = Functions::getConfigNote($contract->hostel);
        $retVal['hostel_name'] = $contract->hostel ? $contract->hostel->name : null;
        $retVal['room_name'] = $contract->room ? $contract->room->name : null;
        $retVal['room_id'] = $contract->room_id;
        $retVal['user'] = $contract->name;
        $retVal['amount'] = intval($sum);
        $retVal['pay'] = intval($pay);
        $retVal['remain'] = intval($remain);
        $retVal['discount'] = intval($discount);
        $retVal['users'] = $userArr;
        $retVal['ids'] = $ids;

        $retVal['contract'] = [
            'id' => $contract->id,
            'name' => $contract->name
        ];


        if ($contract->bed) {
            $retVal['bed'] = [
                'id' => $contract->bed->id,
                'name' => $contract->bed->name
            ];
        }

        return response([
            'status' => 1,
            'data' => $retVal,
            'items' => $items
        ]);
    }

    /**
     * @api {get} /detail-money-info-room-unpaid Chi tiết hóa đơn chưa thanh toán hết của 1 phòng
     * @apiName detail-money-info-room-unpaid
     * @apiGroup Money
     * @apiDescription Api Chi tiết hóa đơn chưa thanh toán hết của 1 phòng
     * @apiParam {String} room_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function detailMoneyInfoRoomUnpaid(Request $request)
    {
        $roomId = $request->input('room_id');
        $contractId = $request->input('contract_id');

        $contract = Contract::find($contractId);
        if (!$contract) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }
        $items = MoneyInfo::query()
            ->when(!empty($roomId), function ($q) use ($roomId) {
                $q->where('room_id', $roomId);
            })
            ->when(!empty($contractId), function ($q) use ($contractId) {
                $q->where('contract_id', $contractId);
            })
            ->where('remain', '<>', 0);

        $sum = clone $items;
        $pay = clone $items;
        $remain = clone $items;
        $discount = clone $items;

        $ids = $items->get()->pluck('id')->toArray();
        $details = MoneyDetail::query()->whereIn('money_info_id', $ids)->get();

        $retVal = [];
        $userArr = [];

//        $sum = $sum->sum('amount');
        $sum = 0;
        $pay = $pay->sum('pay');
        $remain = $remain->sum('remain');
        $discount = $discount->sum('discount');

        foreach ($details as $detail) {
            $sum += !empty($detail->sum_amount) ? $detail->sum_amount : $detail->amount;
            $retVal['items'][] = [
                'id' => $detail->hostel_fee_id,
                'name' => $detail->name,
                'price' => (in_array(optional($detail->hostelFee)->type, [
                    HostelFee::ELECTRIC,
                    HostelFee::WATER
                ])) ? -1 : $detail->value,
                'start_index' => intval($detail->start_index),
                'end_index' => intval($detail->end_index),
                'qty' => intval($detail->qty_text_2),
                'amount' => !empty($detail->sum_amount) ? $detail->sum_amount : $detail->amount,
                'type' => !empty($detail->hostelFee) ? $detail->hostelFee->type : HostelFee::OTHER

            ];
        }

        if ($contract) {
            $users = RenterRoom::selectRaw('users.*')->join('users', 'users.id', '=', 'renter_rooms.user_id')
                ->where('renter_rooms.contract_id', $contract->id)->get();

            foreach ($users as $user) {
                $userArr[] = [
                    'id' => $user->id,
                    'name' => $user->name,
                    'phone' => $user->phone,
                    'email' => $user->email
                ];
            }

        }

        $retVal['name'] = 'Hoá đơn chưa thanh toán hết phòng ' . $contract->room->name;
        $retVal['config_note'] = Functions::getConfigNote($contract->hostel);
        $retVal['hostel_name'] = $contract->hostel ? $contract->hostel->name : null;
        $retVal['room_name'] = $contract->room->name;
        $retVal['room_id'] = $contract->room->id;
        $retVal['amount'] = intval($sum);
        $retVal['pay'] = intval($pay);
        $retVal['remain'] = intval($remain);
        $retVal['discount'] = intval($discount);
        $retVal['users'] = $userArr;
        $retVal['ids'] = $ids;

        $retVal['contract'] = [
            'id' => $contract->id,
            'name' => $contract->name
        ];
        if ($contract->bed) {
            $retVal['bed'] = [
                'id' => $contract->bed->id,
                'name' => $contract->bed->name
            ];
        }

        return response([
            'status' => 1,
            'data' => $retVal
        ]);
    }

    /**
     * @api {post} /delete Xóa phiếu thu chi bất kỳ
     * @apiName delete
     * @apiGroup Money
     * @apiParam {String} id
     * @apiDescription Api Xóa phiếu thu chi bất kỳ
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function destroy(Request $request)
    {
        $id = $request->input('id');
        $item = CollectSpend::find($id);
        if (!$item) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $hostelId = $item->hostel_id;
        $hostel = Hostel::find($hostelId);

        if ($hostel) {
            if ($hostel->owner_id != $this->user->id) {
                return response([
                    'status' => 0,
                    'message' => 'Dữ liệu không hợp lệ'
                ]);
            }
        }
        $transactionId = $item->transaction_id;

        $moneyInfoId = $item->money_info_id;

        DB::beginTransaction();

        try {

            $item->delete();

            $transaction = Transaction::find($transactionId);

            if ($transaction) {
                $transaction->delete();
            }

            $moneyInfo = MoneyInfo::find($moneyInfoId);
            if ($moneyInfo) {
                $paid = Functions::calculateAmountForOrder($moneyInfoId)['pay'];
                $moneyInfo->pay = $paid;
                $moneyInfo->remain = $moneyInfo->amount - $moneyInfo->discount - $paid;
                $moneyInfo->save();
            }

            DB::commit();

        } catch (\Exception $exception) {
            DB::rollBack();

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }
        $typeName = 'thu';
        if ($item->type == CollectSpend::SPEND) {
            $typeName = 'chi';
        }
        $user = Functions::getCurrentUser();
        $desc = '{' . optional($user)->name . '} xóa phiếu ' . $typeName . ' với nội dung {' . $item->name . '}';
        event(new LogAction([
            'type' => 'delete-collect-spend',
            'user_id' => optional($user)->id,
            'object_id' => $item->id,
            'hostel_id' => $item->hostel_id,
            'room_id' => $item->room_id,
            'properties' => $item->toArray(),
            'desc' => $desc
        ]));

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }

    /**
     * @api {post} /paid-full Đánh dấu đã thanh toán đủ
     * @apiName paid-ful
     * @apiGroup Money
     * @apiParam {Array} id[]
     * @apiParam {String} date_action Ngày thanh toán. Dạng d/m/Y
     * @apiParam {String} payer Người thu tiền
     * @apiParam {String} payment_method Phương thức thanh toán. 1 là tiền mặt 2 là chuyển khoản
     * @apiDescription Api đánh dấu nhiều hóa đơn đã thanh toán
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function markPaidFullMoneyInfos(Request $request)
    {
        $ids = $request->input('id');
        $dateAction = $request->input('date_action');
        $payer = $request->input('payer');
        $paymentMethod = $request->input('payment_method');

        if (empty($ids) || !is_array($ids)) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $moneyInfos = MoneyInfo::query()
            ->with([
                'hostel',
                'room'
            ])
            ->whereIn('id', $ids)
            ->get();

        if (empty($dateAction)) {
            $dateAction = Carbon::now()->toDateString();
        } else {
            $dateAction = Carbon::createFromFormat('d/m/Y', $dateAction)->toDateString();
        }

        foreach ($moneyInfos as $moneyInfo) {
            $amount = $moneyInfo->amount - $moneyInfo->discount - $moneyInfo->pay;
            if ($amount == 0) {
                continue;
            }
            $moneyInfo->remain = 0;
            $moneyInfo->pay = $moneyInfo->amount - $moneyInfo->discount;
            $moneyInfo->save();

            $moneyInfoId = $moneyInfo->id;
            $hostelId = $moneyInfo->hostel_id;
            $userId = $this->user->id;
            $roomId = $moneyInfo->room_id;

            $transaction = Transaction::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'date_action' => $dateAction,
                'user_id' => $userId,
                'money_info_id' => $moneyInfoId,
                'type' => CollectSpend::COLLECT,
                'payer' => $payer
            ]);

            CollectSpend::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'room_id' => $roomId,
                'payment_method' => $paymentMethod,
                'date_action' => $dateAction,
                'user_id' => $userId,
                'money_info_id' => $moneyInfoId,
                'type' => CollectSpend::COLLECT,
                'transaction_id' => $transaction->id,
                'payer' => $payer
            ]);
        }

        return response([
            'status' => 1
        ]);
    }

    /**
     * @api {post} /delete-voucher Xóa hóa đơn bất kỳ
     * @apiName delete-voucher
     * @apiGroup Money
     * @apiParam {String} id
     * @apiDescription Api Xóa hóa đơn bất kỳ
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function deleteVoucher(Request $request)
    {
        $id = $request->input('id');
        $voucher = MoneyInfo::find($id);
        if (!$voucher) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        CollectSpend::where('money_info_id', $voucher->id)->delete();
        Transaction::where('money_info_id', $voucher->id)->delete();
        $voucher->delete();

        return response([
            'status' => 1,
            'message' => 'Thanh cong'
        ]);
    }

    /**
     * @api {get} /current-money-info Danh sách hóa đơn hiện tại
     * @apiName current-money-info
     * @apiGroup Money
     * @apiParam {String} start_date Dạng m/Y
     * @apiParam {String} end_date Dạng m/Y
     * @apiParam {String} type 1 là các hóa đơn chưa thanh toán hết, 0 là tất cả hóa đơn, 2 là hóa đơn đã thanh toán hết
     * @apiDescription Api Danh sách hóa đơn hiện tại
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function getCurrentMoney(Request $request)
    {
        $userId = $this->user->id;

        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $type = $request->input('type');
        //   dd($userId);


        $currentRoom = RenterRoom::query()->where('user_id', $userId)
            ->has('hostel')
            ->has('room')
            ->orderBy('created_at', 'desc')
            ->first();
        if (!$currentRoom) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $startDate = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->startOfMonth();
        $endDate = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->startOfMonth();

        $room = $currentRoom->room;
        $hostel = $currentRoom->hostel;

        $retVal = [];
        $sum = 0;
        $amount = 0;
        $payAmount = 0;

        $owner = $this->user;
        if ($this->user->type == User::STAFF) {
            $owner = $this->user->owner;
        } else if ($this->user->type == User::RENTER) {
            $roomRenter = RenterRoom::query()->where('user_id', $this->user->id)->latest()->first();
            if ($roomRenter) {
                $owner = $roomRenter->hostel->owner;
            }
        }
        for ($item = $endDate->copy(); $item->greaterThanOrEqualTo($startDate); $item->subMonth()) {
            $month = $item->month;
            $year = $item->year;

            $startDate2 = Carbon::createFromFormat('d/m/Y', '01/' . $item->month . '/' . $item->year);
            $endDate2 = Carbon::createFromFormat('d/m/Y', '01/' . $item->month . '/' . $item->year);

            $histories = MoneyInfo::query()
                ->where('room_id', $room->id)
                ->with('contract')
                ->where('contract_status', '<>', Contract::LIQUIDATED);


            if ($type == 1) {
                $histories = $histories->where('remain', '>', 0);
            }

            if ($type == 2) {
                $histories = $histories->where('remain', '<=', 0);
            }

            if ($this->user) {
                if ($this->user->type == User::OWNER) {
                    $hostels = Hostel::query()->where('owner_id', $this->user->id)->pluck('id')->toArray();
                    $histories = $histories->whereIn('hostel_id', $hostels);
                }
            }

            if (!empty($hostelId)) {
                $histories = $histories->where('hostel_id', $hostelId);
            }

            if (!empty($roomId)) {
                $histories = $histories->where('room_id', $roomId);
            }

            if ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                $histories = $histories->where('contract_id', $currentRoom->contract_id);
            }

            $histories = $histories->when($owner->type_display_money_info == User::TYPE_DISPLAY_MONEY_INFO_PREVIOUS_MONTH, function ($q) use ($startDate2, $endDate2) {
                $q->where(function ($q) use ($startDate2, $endDate2) {
                    $q->orWhere(function ($q) use ($startDate2, $endDate2) {
                        $q->whereBetween('date_action', [
                            $startDate2->copy()->startOfMonth(),
                            $endDate2->copy()->endOfMonth()
                        ]);
                        $q->whereIn('type', [
                            MoneyInfo::VOUCHER_CONTRACT,
                            MoneyInfo::VOUCHER_ROOM_PRICE
                        ]);
                    });

                    $q->orWhere(function ($q) use ($startDate2, $endDate2) {
                        $q->whereBetween('date_action', [
                            $startDate2->copy()->subMonth()->startOfMonth(),
                            $endDate2->copy()->subMonth()->endOfMonth()
                        ]);
                        $q->where('type', MoneyInfo::VOUCHER_SERVICE);
                    });
                });

            }, function ($q) use ($startDate2, $endDate2) {

                $q->whereBetween('date_action', [
                    $startDate2->copy()->startOfMonth(),
                    $endDate2->copy()->endOfMonth()
                ]);

            });

            $histories = $histories->orderBy('id', 'desc')->get();
            if ($histories->isEmpty()) {
                continue;
            }


            // dd($histories->toSql());

            foreach ($histories as $history) {
                if ($history->hostel_id) {
                    $hostel = Hostel::find($history->hostel_id);
                    if ($hostel) {
                        $history->hostel_name = $hostel->name;
                    } else {
                        $history->hostel_name = '';
                    }
                } else {
                    $history->hostel_name = '';
                }

                if ($history->room_id) {
                    $room = Room::find($history->room_id);
                    if ($room) {
                        $history->room_name = $room->name;
                    } else {
                        $history->room_name = '';
                    }
                } else {
                    $history->room_name = '';
                }
                $sum += $history->amount - $history->discount;
                $amount += $history->amount - $history->discount;

                $pay = \App\Components\Functions::calculateAmountForOrder($history->id)['pay'];
                $history->pay = intval($pay);
                $history->remain = $history->amount - $pay - $history->discount;
                $payAmount += $pay;
            }

            $itemVal = [
                'time' => 'Tháng ' . $month . '/' . $year,
                'histories' => $histories
            ];

            $retVal[] = $itemVal;


        }

        return response([
            'status' => 1,
            'data' => $retVal
        ]);
    }

    /**
     * @api {post} /store-voucher Tạo hóa đơn dịch vụ
     * @apiName store-voucher
     * @apiGroup Money
     * @apiParam {String} contract_id
     * @apiParam {String} qty Số lượng
     * @apiParam {String} fee-contracts Danh sách id các loại phí được lựa chọn
     * @apiParam {String} fee-dynamics Dạng mảng có id là key của phí biến động, value là giá trị
     * @apiParam {String} ew-start Dạng mảng có key là id của điện hoặc nước, value là giá trị đầu
     * @apiParam {String} ew-end Dạng mảng có key là id của điện hoặc nước, value là giá trị cuối
     * @apiParam {String} discount
     * @apiParam {String} month Dạng m/Y
     *     * @apiParam {String} note
     * @apiParam {String} auto_send_invoice Có tự động gửi thông báo invoice hay ko
     * @apiDescription Api Tạo hóa đơn dịch vụ
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function storeVoucherAll(Request $request)
    {
        $qty = $request->input('qty');
        $feeContracts = $request->input('fee-contracts');
        $contractId = $request->input('contract_id');
        $discount = $request->input('discount', 0);
        $ewStart = $request->input('ew-start');
        $ewEnd = $request->input('ew-end');
        $feeDynamics = $request->input('fee-dynamics');
        $autoSendInvoice = $request->input('auto_send_invoice');
        $note = $request->input('note');


        $month = $request->input('month');

        if (empty($discount)) {
            $discount = 0;
        }
        $contract = Contract::find($contractId);

        if (!$contract) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if ($contract->status == Contract::LIQUIDATED) {
            return response([
                'status' => 0,
                'message' => 'Hợp đồng đã được thanh lý'
            ]);
        }

        if (empty($month)) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }


        $contract = Contract::find($contractId);
        $room = $contract->room;

        $sum = 0;

        if (is_array($feeContracts)) {
            foreach ($feeContracts as $feeContract) {
                $start = 0;
                $end = 0;
                if (isset($qty[$feeContract])) {
                    $qtyItem = $qty[$feeContract];
                } else {
                    $qtyItem = 1;
                }

                $feeItem = HostelFee::find($feeContract);
                if ($feeItem) {
                    if ($feeItem->type == HostelFee::ELECTRIC || $feeItem->type == HostelFee::WATER) {
                        if (isset($ewStart[$feeItem->id])) {
                            $start = $ewStart[$feeItem->id];
                        }

                        if (isset($ewEnd[$feeItem->id])) {
                            $end = $ewEnd[$feeItem->id];
                        }

                        $amount = Functions::calculateElectricAmount($end - $start, $room, $feeItem->type, $feeItem->id);
                        $sum += $amount;
                    } else if ($feeItem->type == HostelFee::DYNAMIC || $feeItem->type == HostelFee::WATER_DYNAMIC || $feeItem->type == HostelFee::ELECTRIC_DYNAMIC) {
                        if (isset($feeDynamics[$feeItem->id])) {
                            $amount = $qtyItem * Functions::filterInputNumber($feeDynamics[$feeItem->id]);
                            $sum += $amount;
                        }
                    } else if ($feeItem->type == HostelFee::ELECTRIC_BY_CLOCK || $feeItem->type == HostelFee::WATER_BY_CLOCK) {
                        if (isset($ewStart[$feeItem->id])) {
                            $start = $ewStart[$feeItem->id];
                        }

                        if (isset($ewEnd[$feeItem->id])) {
                            $end = $ewEnd[$feeItem->id];
                        }

                        $amount = ($end - $start) * $feeItem->fee;
                        $sum += $amount;
                    } else {
                        $amount = $qtyItem * $feeItem->fee;
                        $sum += $amount;
                    }
                }
            }
        }

        try {
            $dateAction = Carbon::createFromFormat('d/m/Y', '01/' . $month)->toDateString();

            \DB::beginTransaction();
            try {
                $startTime = Carbon::createFromFormat('d/m/Y', '01/' . $month)->startOfMonth()->startOfDay()->toDateTimeString();
                $endTime = Carbon::createFromFormat('d/m/Y', '01/' . $month)->endOfMonth()->endOfDay()->toDateTimeString();
                $monthCarbon = Carbon::createFromFormat('d/m/Y', '01/' . $month);
            } catch (\Exception $exception) {
                return response([
                    'status' => 0,
                    'message' => 'Dữ liệu ngày tháng phải có định dạng tháng / năm. Ví dụ: 06/2018'
                ]);
            }


            $item = MoneyInfo::where('room_id', $room->id)
                ->where('type', MoneyInfo::VOUCHER_SERVICE)
                ->validate($contract->id)
                ->whereBetween(
                    'date_action', [$startTime, $endTime]
                )->first();

            $pay = 0;
            $itemId = null;
            if ($item) {
                $cntCollectSpend = CollectSpend::query()
                    ->where('money_info_id', $item->id)
                    ->first();
                if ($cntCollectSpend) {
                    return response([
                        'status' => 0,
                        'message' => 'Đã tồn tại hóa đơn được thanh toán trước đó cho tháng ' . $monthCarbon->copy()->format('m/Y') . '. Mã hóa đơn: ' . $item->name . ', mã phiếu thu chi: ' . $cntCollectSpend->code
                    ]);
                }
                $itemId = $item->id;
                $dateAction = $item->date_action->toDateString();

                if ($item->pay > 0) {
                    $pay = $item->pay;
                }
                MoneyDetail::where('money_info_id', $item->id)->delete();
                MoneyInfo::find($item->id)->delete();
                ElectricWater::query()->whereBetween('date_action', [
                    $startTime,
                    $endTime
                ])
                    ->where('contract_id', $contractId)
                    ->where('room_id', $room->id)->delete();
                $user = Functions::getCurrentUser();

                $desc = '{' . $user->name . '} vừa sửa hóa đơn dịch vụ tháng {' . $monthCarbon->copy()->format('m/Y') . '} cho khách {' . $contract->name . '} phòng {' . $contract->room->name . '} nhà {' . $contract->hostel->name . '}';
                if ($contract->hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                    $desc = '{' . $user->name . '} vừa sửa hóa đơn dịch vụ tháng {' . $monthCarbon->copy()->format('m/Y') . '} cho khách {' . $contract->name . '} giường {' . optional($contract->bed)->name . '} phòng {' . $contract->room->name . '} nhà {' . $contract->hostel->name . '}';
                }
                event(new LogAction([
                    'type' => 'update-money-info-service',
                    'user_id' => optional($user)->id,
                    'object_id' => $item->id,
                    'hostel_id' => $contract->hostel_id,
                    'room_id' => $contract->room_id,
                    'desc' => $desc
                ]));

            }

            $moneyInfo = MoneyInfo::create([
                'hostel_id' => $contract->room->hostel->id,
                'user_id' => $this->user->id,
                'room_id' => $contract->room->id,
                'amount' => $sum,
                'discount' => $discount,
                'pay' => $pay,
                'remain' => $sum - $discount - $pay,
                'date_action' => $dateAction,
                'type' => MoneyInfo::VOUCHER_SERVICE,
                'contract_id' => $contract->id,
                'note' => $note
            ]);

            if (!$item) {
                $user = Functions::getCurrentUser();
                $desc = '{' . optional($user)->name . '}' . ' vừa lập hóa đơn dịch vụ tháng {' . $moneyInfo->date_action->format('m/Y') . '} 
                cho khách {' . $moneyInfo->contract->name . '} phòng {' . $moneyInfo->room->name . '} nhà {' . $moneyInfo->hostel->name . '}';
                if ($moneyInfo->hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                    $desc = '{' . optional($user)->name . '}' . ' vừa lập hóa đơn dịch vụ tháng {' . $moneyInfo->date_action->format('m/Y') . '} 
                cho khách {' . $moneyInfo->contract->name . '} giường {' . optional($moneyInfo->contract->bed)->name . '} phòng {' . $moneyInfo->room->name . '} nhà {' . $moneyInfo->hostel->name . '}';
                }

                event(new LogAction([
                    'type' => 'create-money-info-service',
                    'user_id' => optional($user)->id,
                    'object_id' => $moneyInfo->id,
                    'hostel_id' => $moneyInfo->hostel_id,
                    'room_id' => $moneyInfo->room_id,
                    'properties' => $moneyInfo->toArray(),
                    'desc' => $desc
                ]));
            }

            if (!empty($itemId)) {
                Transaction::where('money_info_id', $itemId)->update([
                    'money_info_id' => $moneyInfo->id
                ]);

                CollectSpend::where('money_info_id', $itemId)->update([
                    'money_info_id' => $moneyInfo->id,
                    'money_info_name' => $moneyInfo->name
                ]);
            }

            if (is_array($feeContracts)) {
                foreach ($feeContracts as $feeContract) {

                    if (isset($qty[$feeContract])) {
                        $qtyItem = $qty[$feeContract];
                    } else {
                        $qtyItem = 1;
                    }

                    $feeItem = HostelFee::find($feeContract);

                    $isElectric = 0;
                    $isWater = 0;
                    $feeValue = 1;
                    $feeId = 0;
                    if ($feeItem) {
                        $feeValue = $feeItem->fee;
                        $amount = $feeValue * $qtyItem;
                        if ($feeItem->type == HostelFee::ELECTRIC || $feeItem->type == HostelFee::ELECTRIC_BY_CLOCK) {
                            $isElectric = 1;
                            if ($ewEnd[$feeItem->id] < $ewStart[$feeItem->id]) {
                                return response([
                                    'status' => 0,
                                    'message' => 'Chỉ số cuối không được nhỏ hơn chỉ số đầu'
                                ]);
                            }
                            $qtyItem = json_encode([
                                'start' => $ewStart[$feeItem->id],
                                'end' => $ewEnd[$feeItem->id]
                            ]);


                            $ew['end_electric'] = $ewEnd[$feeItem->id];
                            $ew['start_electric'] = $ewStart[$feeItem->id];
                            $ew['delta_electric'] = $ew['end_electric'] - $ew['start_electric'];
                            $ew['date_action'] = Carbon::createFromFormat('d/m/Y', '01/' . $month)->toDateTimeString();
                            $ew['room_id'] = $room->id;
                            $ew['hostel_id'] = $room->hostel->id;
                            $ew['contract_id'] = $contractId;
                            $feeValue = 1;
                            if ($feeItem->type == HostelFee::ELECTRIC) {
                                $amount = Functions::calculateElectricAmount($ewEnd[$feeItem->id] - $ewStart[$feeItem->id], $room, HostelFee::ELECTRIC, $feeItem->id);
                            } else {
                                $feeValue = $feeItem->fee;
                                $amount = ($ewEnd[$feeItem->id] - $ewStart[$feeItem->id]) * $feeItem->fee;
                            }

                            $itemEw = ElectricWater::query()->whereBetween('date_action', [
                                $startTime,
                                $endTime
                            ])->where('contract_id', $contractId)
                                ->where('room_id', $room->id)->first();
                            if ($itemEw) {
                                $itemEw->update($ew);
                            } else {
                                ElectricWater::create($ew);
                            }

                        } else if ($feeItem->type == HostelFee::WATER || $feeItem->type == HostelFee::WATER_BY_CLOCK) {
                            $isWater = 1;

                            if ($ewEnd[$feeItem->id] < $ewStart[$feeItem->id]) {
                                return response([
                                    'status' => 0,
                                    'message' => 'Chỉ số cuối không được nhỏ hơn chỉ số đầu'
                                ]);
                            }
                            $qtyItem = json_encode([
                                'start' => $ewStart[$feeItem->id],
                                'end' => $ewEnd[$feeItem->id]
                            ]);

                            $ew['end_water'] = $ewEnd[$feeItem->id];
                            $ew['start_water'] = $ewStart[$feeItem->id];
                            $ew['delta_water'] = $ew['end_water'] - $ew['start_water'];
                            $ew['date_action'] = Carbon::createFromFormat('d/m/Y', '01/' . $month)->toDateString();
                            $ew['room_id'] = $room->id;
                            $ew['hostel_id'] = $room->hostel->id;
                            $ew['contract_id'] = $contractId;

                            $feeValue = 1;
                            if ($feeItem->type == HostelFee::WATER) {
                                $amount = Functions::calculateElectricAmount($ewEnd[$feeItem->id] - $ewStart[$feeItem->id], $room, HostelFee::WATER, $feeItem->id);
                            } else {
                                $feeValue = $feeItem->fee;
                                $amount = ($ewEnd[$feeItem->id] - $ewStart[$feeItem->id]) * $feeItem->fee;
                            }

                            $itemEw = ElectricWater::whereBetween('date_action', [
                                $startTime,
                                $endTime
                            ])
                                ->where('contract_id', $contractId)
                                ->where('room_id', $room->id)
                                ->first();
                            if ($itemEw) {
                                $itemEw->update($ew);
                            } else {
                                ElectricWater::create($ew);
                            }
                        } else if ($feeItem->type == HostelFee::DYNAMIC || $feeItem->type == HostelFee::WATER_DYNAMIC || $feeItem->type == HostelFee::ELECTRIC_DYNAMIC) {

                            if (isset($feeDynamics[$feeItem->id])) {
                                $feeValue = Functions::filterInputNumber($feeDynamics[$feeItem->id]);
                                $amount = $feeValue * $qtyItem;
                            }
                        }


                        $name = $feeItem->name;
                        $feeId = $feeItem->id;

                    } else {
                        $name = 'Khác';
                    }

                    MoneyDetail::create([
                        'hostel_id' => $contract->room->hostel->id,
                        'room_id' => $contract->room->id,
                        'name' => $name,
                        'is_electric' => $isElectric,
                        'is_water' => $isWater,
                        'money_info_id' => $moneyInfo->id,
                        'value' => $feeValue,
                        'qty' => $qtyItem,
                        'amount' => $amount,
                        'hostel_fee_id' => $feeId,
                    ]);
                }
            }

            \DB::commit();

            if ($autoSendInvoice == 1) {
                $moneyInfoId = $moneyInfo->id;
                $fromUser = $this->user->id;
                $token = $this->user->token;
                $details = MoneyDetail::query()->where('money_info_id', $moneyInfoId)->get();
                if ($details->count() <= 0) {
                    return response([
                        'status' => 0,
                        'message' => 'Dữ liệu không hợp lệ'
                    ]);
                }

                //$message = view( 'admin2.money.message', compact( 'moneyInfo', 'details' ) )->render();
                $message = 'Hoá đơn tiền dịch vụ tháng ' . $moneyInfo->date_action->copy()->format('m/Y') . ' đã được lập, xem chi tiết tại: ' . url('bill/print?token=' . $token, ['id' => $moneyInfo->id]);

                $conversation = Conversation::query()->where('room_id', $room->id)
                    ->whereNotNull('hostel_id')
                    ->first();

                if (!$conversation) {
                    return response([
                        'status' => 0,
                        'message' => 'Dữ liệu không hợp lệ'
                    ]);
                }

                $message = Message::create([
                    'content' => $message,
                    'conversation_id' => $conversation->id,
                    'type' => Message::TYPE_TEXT,
                    'from' => $fromUser
                ]);


                $conversation->update([
                    'last_message_id' => $message->id,
                    'last_message_time' => Carbon::now()->toDateTimeString()
                ]);

                $messageArr = $message->toArray();
                $content = $message->content;
                $userOnlineArr = [];

                if (isset($usersChannel['result'])) {
                    if (isset($usersChannel['result']['users'])) {
                        foreach ($usersChannel['result']['users'] as $item) {
                            $userIdOnline = $item['id'];
                            $userOnlineArr[] = $userIdOnline;
                        }
                    }
                }


                $membersArr = \DB::table('user_conversations')->where('conversation_id', $conversation->id)->pluck('user_id')->toArray();

                foreach ($membersArr as $userId) {


                    $q = \DB::table('user_conversations')
                        ->where('conversation_id', $conversation->id)
                        ->where('user_id', $userId);

                    if (in_array($userId, $userOnlineArr)) {
                        $q->update([
                            'is_read_last_message' => 1
                        ]);
                    } else {
                        $q->update([
                            'is_read_last_message' => 0
                        ]);
                    }

                    if ($message->type == Message::TYPE_IMAGE || $message->type == Message::TYPE_SYSTEM) {
                        if ($userId == $fromUser) {
                            if ($message->type == Message::TYPE_IMAGE) {
                                $content = 'Bạn đã gửi một ảnh';
                            } else {
                                $content = 'Bạn ' . $content;
                            }
                        } else {
                            $fromUser = $message->fromUser;
                            if ($fromUser) {
                                if ($message->type == Message::TYPE_IMAGE) {
                                    $content = $fromUser->name_text . ' đã gửi một ảnh';
                                } else {
                                    $content = $fromUser->name_text . ' ' . $content;
                                }
                            }
                        }

                    }

                    $messageArr['content'] = $content;


                    $this->pusher->trigger('chat-' . $userId, 'new-message', $messageArr);

                    dispatch(new SendNotificationMessage($userId, $messageArr));

                    dispatch(new SendMailRentersMoney($moneyInfoId));

                }
            }


        } catch (\Exception $exception) {
            \DB::rollBack();

            \Log::info($exception->getMessage() . '|' . $exception->getLine());

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);

//        if(em)
    }

    /**
     * @api {get} /paid-room Danh sách thu tiền phòng
     * @apiName paid-room
     * @apiGroup Money
     * @apiParam {String} room_id
     * @apiParam {String} start_date Dạng m/Y
     * @apiParam {String} end_date Dạng m/Y
     * @apiDescription Api Danh sách thu tiền phòng
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function paymentHistory(Request $request)
    {
        $roomId = $request->input('room_id');
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $userId = $this->user->id;


        $room = Room::find($roomId);
        $retVal = [];

        if ($room) {

            $currentRoom = RenterRoom::query()->where('user_id', $userId)
                ->where('room_id', $roomId)
                ->first();

            $times = CollectSpend::query()->select(\DB::raw('MONTH(collect_spends.date_action) as month, YEAR(collect_spends.date_action) as year'))
                ->where('room_id', $roomId)
                ->groupBy(\DB::raw('month, year'));

            if (!empty($startDate)) {
                $startDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$startDate)->startOfMonth()->toDateString();
                $times = $times->where('collect_spends.date_action', '>=', $startDateAction);
            }

            if (!empty($endDate)) {
                $endDateAction = Carbon::createFromFormat('d/m/Y', '01/'.$endDate)->endOfMonth()->toDateString();
                $times = $times->where('collect_spends.date_action', '<=', $endDateAction);
            }

            if ($currentRoom) {
                if ($room->hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                    $times = $times->where('contract_id', $currentRoom->contract_id);
                }
            }

            $times = $times->orderBy('month', 'desc')->orderBy('year', 'desc')->get();
            $sum = 0;

            foreach ($times as $time) {

                $month = $time->month;
                $year = $time->year;

                $startDate = Carbon::createFromFormat('d/m/Y','01/'. $time->month . '/' . $time->year)->startOfMonth()->toDateTimeString();
                $endDate = Carbon::createFromFormat('d/m/Y', '01/'.$time->month . '/' . $time->year)->endOfMonth()->toDateTimeString();

                $items = CollectSpend::query()->where('type', CollectSpend::COLLECT)
                    ->with([
                        'contract',
                        'hostel'
                    ])
                    ->where(function ($q) {
                        $q->orWhereNull('contract_id');
                        $q->orWhereHas('contract', function ($q) {
                            $q->where('status', '<>', Contract::LIQUIDATED);
                        });
                    })
                    ->where('room_id', $roomId);

                if ($currentRoom) {
                    if ($currentRoom->hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                        $items = $items->where('contract_id', $currentRoom->contract_id);
                    }
                }

                //  $items = Transaction::whereIn('id', $itemsTransactions);

                if (!empty($startDate) && !empty($endDate)) {
                    $items = $items->whereBetween('collect_spends.date_action', [$startDate, $endDate]);
                }

                if (!empty($hostelId)) {
                    $items = $items->where('collect_spends.hostel_id', $hostelId);
                }

                $items = $items->orderBy('collect_spends.id', 'desc')->get();

                foreach ($items as $key => $item) {
                    if ($item->hostel) {
                        $item->hostel_name = $item->hostel->name;
                        unset($item->hostel);
                    } else {
                        $item->hostel_name = '';
                    }
                    $item->type_name = Functions::getTypeCpName($item);
                    $sum += $item->amount;
                    if ($item->user) {
                        $userArr = $item->user->toArray();
                        $userArr['name'] = $item->user->name_text;
                        unset($item->user);
                        $item->user = $userArr;
                    }
                }

                $itemVal = [
                    'time' => 'Tháng ' . $month . '/' . $year,
                    'histories' => $items
                ];

                if ($items->count() > 0) {

                    $retVal[] = $itemVal;
                }
            }


            return response([
                'status' => 1,
                'sum' => $sum,
                'data' => $retVal
            ]);
        }

        return response([
            'status' => 0,
            'message' => 'Dữ liệu không hợp lệ'
        ]);

    }


    /**
     * @api {post} /spend Tạo phiếu chi
     * @apiName spend
     * @apiGroup Money
     * @apiParam {String} amount
     * @apiParam {String} room_id
     * @apiParam {String} hostel_id
     * @apiParam {String} name Lý do chi
     * @apiParam {String} date_action Ngày chi Gửi lên dạng d/m/Y
     * @apiParam {String} type_purpose Loại chi. id loại phiếu chi
     * @apiParam {String} receiver Người nhận
     * @apiParam {String} payment_method 1 là tiền mặt, 2 là chuyển khoản
     * @apiParam {String} note ghi chú
     *
     * @apiDescription Api Tạo phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function spend2(Request $request)
    {
        $data = $request->except([
            'repeat_every',
            'repeat_every_custom',
            'repeat_type_custom',
            'cycles',
            'unlimited_cycles'
        ]);
        $roomId = null;
        $hostelId = null;

        $amount = $data['amount'];

        $ownerId = $this->user->id;
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }

        $amount = Functions::filterInputNumber($amount);

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền phải là số'
            ]);
        }

        if (!empty($data['date_action'])) {
            $dateAction = Carbon::createFromFormat('d/m/Y', $data['date_action'])->toDateString();
        } else {
            $dateAction = Carbon::now()->toDateString();
        }

        if (isset($data['room_id'])) {
            $roomId = $data['room_id'];
        }

        if (isset($data['hostel_id'])) {
            $hostelId = $data['hostel_id'];
        }


        try {
            \DB::beginTransaction();

            $transaction = Transaction::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'room_id' => $roomId,
                'date_action' => $dateAction,
                'type' => CollectSpend::SPEND,
            ]);

            $cp = CollectSpend::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'room_id' => $roomId,
                'note' => isset($data['note']) ? $data['note'] : null,
                'payment_method' => isset($data['payment_method']) ? $data['payment_method'] : null,
                'date_action' => $dateAction,
                'type' => CollectSpend::SPEND,
                'receiver' => isset($data['receiver']) ? $data['receiver'] : null,
                'name' => isset($data['name']) ? $data['name'] : null,
                'transaction_id' => $transaction->id,
                'type_purpose' => isset($data['type_purpose']) ? $data['type_purpose'] : null,
                'owner_id' => $ownerId,
                'is_allow_cycle' => true
            ]);

            if (isset($data['receiver'])) {
                $cnt = Receiver::where('name', trim($data['receiver']))
                    ->where('user_id', $this->user->id)->count();

                if ($cnt == 0) {
                    Receiver::create([
                        'user_id' => $this->user->id,
                        'name' => $data['receiver']
                    ]);
                }
            }

            \DB::commit();

            $files = $request->file('files');
            if (!empty($files) && is_array($files)) {
                foreach ($files as $key => $file) {
                    $name = time() . $file->getClientOriginalName();
                    $filePath = 'collect-spends/' . $cp->id . '/files/' . str_slug($name);
                    $filePath = $filePath . '.' . $file->getClientOriginalExtension();
                    \Storage::disk('s3')->put($filePath, file_get_contents($file), 'public');
                    CollectSpendFile::create([
                        'collect_spend_id' => $cp->id,
                        'name' => $file->getClientOriginalName(),
                        'file' => 'https://resident.sgp1.digitaloceanspaces.com/' . $filePath
                    ]);
                }
            }

            $repeatEvery = $request->input('repeat_every');
            if ($repeatEvery) {
                CollectSpendCycle::query()->updateOrCreate([
                    'collect_spend_id' => $cp->id,
                ], [
                    'collect_spend_id' => $cp->id,
                    'repeat_every' => $request->input('repeat_every'),
                    'repeat_every_custom' => $request->input('repeat_every_custom'),
                    'repeat_type_custom' => $request->input('repeat_type_custom'),
                    'cycles' => $request->input('cycles'),
                    'unlimited_cycles' => !empty($request->input('unlimited_cycles')),

                ]);
            } else {
                CollectSpendCycle::query()
                    ->where('collect_spend_id', $cp->id)
                    ->delete();
            }

            $user = Functions::getCurrentUser();
            $desc = '{' . optional($user)->name . '} vừa chi {' . number_format($cp->amount, 0, '.', '.') . '} với nội dung {' . $request->input('name') . '}';
            event(new LogAction([
                'type' => 'create-spend',
                'user_id' => optional($user)->id,
                'object_id' => $cp->id,
                'hostel_id' => $cp->hostel_id,
                'room_id' => $cp->room_id,
                'properties' => $cp->toArray(),
                'desc' => $desc
            ]));

        } catch (\Exception $exception) {
            \DB::rollBack();

            // dd($exception->getMessage(). '|'.$exception->getLine());

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }


    /**
     * @api {post} /edit-spend Cập nhật phiếu chi
     * @apiName /edit-spend
     * @apiGroup Money
     * @apiParam {String} amount
     * @apiParam {String} name Lý do chi
     * @apiParam {String} date_action Ngày chi Gửi lên dạng d/m/Y
     * @apiParam {String} receiver Người nhận
     * @apiParam {String} payment_method 1 là tiền mặt, 2 là chuyển khoản
     * @apiParam {String} note ghi chú
     * @apiParam {String} id Id của phiếu chi
     *
     *
     *
     * @apiParam {String} repeat_every Lặp lại theo chu kỳ định sẵn. Nếu field này rỗng tức là ko áp dụng lặp lại
     * @apiParam {String} repeat_every_custom Lặp lại theo chu kỳ custom. Field này là số
     * @apiParam {String} repeat_type_custom Loại của chu kỳ custom. 1,2,3,4 tương ứng là ngày, tuần tháng năm
     * @apiParam {String} cycles Số lần lặp lại, dạng số
     * @apiParam {String} unlimited_cycles Lặp vô hạn. Truyền lên true false. Nếu trường này là true thì backend tự động bỏ qua field cycles kia.
     *
     * @apiDescription Api  Cập nhật phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function edit(Request $request)
    {
        $data = $request->except([
            'repeat_every',
            'repeat_every_custom',
            'repeat_type_custom',
            'cycles',
            'unlimited_cycles'
        ]);

        $amount = $data['amount'];

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }

        $amount = Functions::filterInputNumber($amount);
        $data['amount'] = $amount;

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền phải là số'
            ]);
        }

        if (!empty($data['date_action'])) {
            $data['date_action'] = Carbon::createFromFormat('d/m/Y', $data['date_action'])->toDateString();
        } else {
            $data['date_action'] = Carbon::now()->toDateString();
        }


        try {
            \DB::beginTransaction();

            $collectSpend = CollectSpend::find($data['id']);

            if (!$collectSpend) {
                return response([
                    'status' => 0,
                    'message' => 'Dữ liệu không hợp lệ'
                ]);
            }

            $collectSpend->update($data);

            $dateAction = $collectSpend->date_action;
            if (!empty($dateAction)) {
                $month = $collectSpend->date_action->month;
                $year = $collectSpend->date_action->year;
                StatisticLog::query()->where('collect_spend_id', $collectSpend->id)
                    ->update([
                        'month' => $month,
                        'year' => $year
                    ]);
            }

            $transactionId = $collectSpend->transaction_id;
            $transaction = Transaction::find($transactionId);

            if ($transaction) {
                $transaction->amount = $amount;
                $transaction->save();
            }

            $paid = Transaction::where('money_info_id', $transaction->money_info_id)->sum('amount');
            $moneyInfo = MoneyInfo::find($transaction->money_info_id);
            if ($moneyInfo) {
                $moneyInfo->pay = $paid;
                $moneyInfo->remain = $moneyInfo->amount - $moneyInfo->discount - $paid;
                $moneyInfo->save();
            }

            if (isset($data['receiver'])) {
                $cnt = Receiver::where('name', trim($data['receiver']))
                    ->where('user_id', $this->user->id)->count();

                if ($cnt == 0) {
                    Receiver::create([
                        'user_id' => $this->user->id,
                        'name' => $data['receiver']
                    ]);
                }
            }

            \DB::commit();

            $files = $request->file('files');
            if (!empty($files) && is_array($files)) {
                foreach ($files as $key => $file) {
                    $name = time() . $file->getClientOriginalName();
                    $filePath = 'collect-spends/' . $collectSpend->id . '/files/' . str_slug($name);
                    $filePath = $filePath . '.' . $file->getClientOriginalExtension();
                    \Storage::disk('s3')->put($filePath, file_get_contents($file), 'public');
                    CollectSpendFile::create([
                        'collect_spend_id' => $collectSpend->id,
                        'name' => $file->getClientOriginalName(),
                        'file' => 'https://resident.sgp1.digitaloceanspaces.com/' . $filePath
                    ]);
                }
            }

            $deletedFiles = $request->input('deleted_files');
            if (is_array($deletedFiles) && !empty($deletedFiles)) {
                CollectSpendFile::query()->whereIn('id', $deletedFiles)->delete();
            }

            $repeatEvery = $request->input('repeat_every');
            if (!empty($repeatEvery)) {
                CollectSpendCycle::query()->updateOrCreate([
                    'collect_spend_id' => $collectSpend->id,
                ], [
                    'collect_spend_id' => $collectSpend->id,
                    'repeat_every' => $request->input('repeat_every'),
                    'repeat_every_custom' => $request->input('repeat_every_custom'),
                    'repeat_type_custom' => $request->input('repeat_type_custom'),
                    'cycles' => $request->input('cycles'),
                    'unlimited_cycles' => !empty($request->input('unlimited_cycles')),

                ]);
            } else {
                CollectSpendCycle::query()
                    ->where('collect_spend_id', $collectSpend->id)
                    ->delete();
            }

            $user = Functions::getCurrentUser();
            $desc = '{'.$user->name.'} sửa phiếu chi {'.$collectSpend->name.'}';
            event(new LogAction([
                'type' => 'update-spend',
                'user_id' => optional($user)->id,
                'object_id' => $collectSpend->id,
                'hostel_id' => $collectSpend->hostel_id,
                'room_id' => $collectSpend->room_id,
                'properties' => $collectSpend->toArray(),
                'desc' => $desc
            ]));

        } catch (\Exception $exception) {
            \DB::rollBack();

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }

    /**
     * @api {get} /room-fee Lấy các dịch vụ phòng
     * @apiName /room-fee
     * @apiGroup Money
     * @apiParam {String} room_id
     *
     * @apiDescription Api Lấy các dịch vụ phòng
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     *
     */
    public function getRoomFee(Request $request)
    {
        $roomId = $request->input('room_id');
        $contractId = $request->input('contract_id');
        $room = Room::find($roomId);

        if (!$room) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        $contract = Contract::where('room_id', $roomId)->where('status', '<>', Contract::LIQUIDATED)->first();

        if (!empty($contractId)) {
            $contract = Contract::find($contractId);
        }

        if ($contract) {

            if ($contract->hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                $fees = ContractFee::select(DB::raw('hostel_fees.*, contract_fees.qty'))->join('hostel_fees', 'contract_fees.fee_id', '=', 'hostel_fees.id')
                    ->where('hostel_fees.type', '<>', HostelFee::ELECTRIC)->where('hostel_fees.type', '<>', HostelFee::WATER)
                    ->where('contract_fees.contract_id', $contract->id)
                    ->get();
            } else {
                $fees = ContractFee::select(DB::raw('hostel_fees.*, contract_fees.qty'))->join('hostel_fees', 'contract_fees.fee_id', '=', 'hostel_fees.id')
                    ->where('contract_fees.contract_id', $contract->id)
                    ->get();
            }

            $hostelFees = HostelFee::where('hostel_id', $room->hostel_id)->pluck('id')->toArray();

            foreach ($fees as $fee) {
                if (in_array($fee->id, $hostelFees)) {
                    $fee->is_checked = true;
                } else {
                    $fee->is_checked = false;
                }
            }

            return response([
                'status' => 1,
                'data' => $fees
            ]);
        }

        return response([
            'status' => 1,
            'data' => null
        ]);
    }

    /**
     * @api {get} /calculate-ew Tính tiền điện nước
     * @apiName /calculate-ew
     * @apiGroup Money
     * @apiParam {String} room_id
     * @apiParam {String} fee_id
     * @apiParam {String} delta
     * @apiParam {String} type 1 là điện 2 là nước
     *
     * @apiDescription Api Lấy các dịch vụ phòng
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function calculateEw(Request $request)
    {
        $type = $request->input('type');
        $delta = $request->input('delta');
        $roomId = $request->input('room_id');
        $feeId = $request->input('fee_id');

        $room = Room::find($roomId);

        if (!$room) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }


        $fee = HostelFee::find($feeId);

        if (!$fee) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if ($fee->type == HostelFee::ELECTRIC_BY_CLOCK || $fee->type == HostelFee::WATER_BY_CLOCK ||
            $fee->type == HostelFee::ELECTRIC_BY_PEOPLE || $fee->type == HostelFee::WATER_BY_PEOPLE
        ) {
            $amount = $fee->fee * $delta;
        } else {

            $amount = Functions::calculateElectricAmount($delta, $room, $type, $feeId);
        }

        return response([
            'status' => 1,
            'data' => $amount
        ]);

    }

    /**
     * @api {get} /detail-voucher Chi tiết voucher
     * @apiName /detail-voucher
     * @apiGroup Money
     * @apiParam {String} room_id
     * @apiParam {String} month
     * @apiParam {String} contract_id
     *
     * @apiDescription Api Lấy Chi tiết voucher
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function getVoucherByParam(Request $request)
    {
        $roomId = $request->input('room_id');
        $month = $request->input('month');
        $contractId = $request->input('contract_id');
        $room = Room::find($roomId);


        if (!$room) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if (empty($month)) {
            $month = Carbon::now()->format('m/Y');
        }


        if (!empty($contractId)) {
            $contract = Contract::query()->find($contractId);
        } else {
            $contract = Contract::query()->where('room_id', $roomId)
                ->where('status', '<>', Contract::LIQUIDATED)->first();
        }

        if (!$contract) {
            return response([
                'status' => 0,
                'message' => 'Không tìm thấy HĐ'
            ]);
        }
        try {

            $date = Carbon::createFromFormat('d/m/Y', '01/' . $month);

            $startTime = $date->copy()->subMonth()->startOfMonth()->startOfDay()->toDateString();
            $endTime = $date->copy()->subMonth()->endOfMonth()->endOfDay()->toDateString();

        } catch (\Exception $exception) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu ngày tháng phải có định dạng tháng / năm. Ví dụ: 06/2018'
            ]);
        }


        $item = MoneyInfo::query()->where('room_id', $room->id)
            ->where('type', MoneyInfo::VOUCHER_SERVICE)
            ->validate($contract->id)
            ->where('date_action', '<', $date->copy()->startOfMonth()->startOfDay())
            ->orderBy('date_action', 'desc')
            ->first();


        $currentItem = MoneyInfo::query()->where('room_id', $room->id)
            ->where('type', MoneyInfo::VOUCHER_SERVICE)
            ->validate($contract->id)
            ->whereBetween(
                'date_action', [
                    $date->copy()->startOfMonth()->startOfDay(),
                    $date->copy()->endOfMonth()->endOfDay()
                ]
            )->first();

        if ($currentItem) {
            $item = clone $currentItem;
        }


        $feeArr = [];
        $hostelFees = HostelFee::query()
            ->where('hostel_id', $room->hostel->id)
            ->get();
        if ($item) {


            $fees = MoneyDetail::query()
                ->where('money_info_id', $item->id)
                ->pluck('hostel_fee_id')
                ->toArray();

            foreach ($hostelFees as $hostelFee) {
                $isEnable = false;
                $start = 0;
                $end = 0;

                $moneyDetail = MoneyDetail::query()
                    ->where('money_info_id', $item->id)
                    ->where('hostel_fee_id', $hostelFee->id)
                    ->first();

                $contractFee = ContractFee::query()->where('contract_id', $contract->id)
                    ->where('fee_id', $hostelFee->id)->first();
                if (is_array($fees) && in_array($hostelFee->id, $fees)) {
                    $isEnable = true;
                }


                $isCurrent = true;
                $currentEwInfo = ElectricWater::query()
                    ->where('contract_id', $contract->id)
                    ->where('hostel_id', $contract->hostel->id)
                    ->where('room_id', $contract->room->id)
                    ->whereBetween('date_action', [
                        $date->copy()->startOfMonth(),
                        $date->copy()->endOfMonth()
                    ])
                    ->latest()
                    ->first();


                if (!$currentEwInfo) {
                    $isCurrent = false;
                    $currentEwInfo =
                        ElectricWater::query()->where('hostel_id', $contract->hostel->id)
                            ->where('room_id', $contract->room->id)
                            ->where('contract_id', $contract->id)
                            ->where('date_action', '<', $date->copy()->startOfMonth())
                            ->orderBy('date_action', 'desc')
                            ->first();
                }

                if ($moneyDetail) {
                    $info = json_decode($moneyDetail->qty, true);
                    $start = $info['start'];
                    $end = $info['end'];
//                        dd($info);

                    if (!$currentItem) {

                        if ($currentEwInfo) {
                            if ($isCurrent) {
                                if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK) {
                                    $start = $currentEwInfo->start_electric;
                                    $end = $currentEwInfo->end_electric;

                                } else if ($hostelFee->type == HostelFee::WATER || $hostelFee->type == HostelFee::WATER_BY_CLOCK) {
                                    $start = $currentEwInfo->start_water;
                                    $end = $currentEwInfo->end_water;

                                }
                            } else {
                                if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK) {
                                    $start = $currentEwInfo->end_electric;
                                    $end = 0;

                                } else if ($hostelFee->type == HostelFee::WATER || $hostelFee->type == HostelFee::WATER_BY_CLOCK) {
                                    $start = $currentEwInfo->end_water;
                                    $end = 0;

                                }
                            }
                        } else {

                            $start = $info['end'];
                            $end = 0;
                        }
                    } else if ($isCurrent) {
                        if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK) {
                            $start = $currentEwInfo->start_electric;
                            $end = $currentEwInfo->end_electric;

                        } else if ($hostelFee->type == HostelFee::WATER || $hostelFee->type == HostelFee::WATER_BY_CLOCK) {
                            $start = $currentEwInfo->start_water;
                            $end = $currentEwInfo->end_water;

                        }
                    }

                } else if ($currentEwInfo) {

                    if ($isCurrent) {
                        if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK) {
                            $start = $currentEwInfo->start_electric;
                            $end = $currentEwInfo->end_electric;

                        } else if ($hostelFee->type == HostelFee::WATER || $hostelFee->type == HostelFee::WATER_BY_CLOCK) {
                            $start = $currentEwInfo->start_water;
                            $end = $currentEwInfo->end_water;

                        }
                    } else {
                        if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK) {
                            $start = $currentEwInfo->end_electric;
                            $end = 0;

                        } else if ($hostelFee->type == HostelFee::WATER || $hostelFee->type == HostelFee::WATER_BY_CLOCK) {
                            $start = $currentEwInfo->end_water;
                            $end = 0;

                        }
                    }
                }


//                    if($hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK || $hostelFee->type == HostelFee::WATER_BY_CLOCK)
//                    {
//
//                    }

                $qty = 1;
                $amount = $hostelFee->fee * 1;

                if ($contractFee) {
                    $qty = $contractFee->qty;
                    $amount = $hostelFee->fee * $contractFee->qty;
                }

                if ($currentItem) {
                    if ($moneyDetail) {
                        $qty = $moneyDetail->qty;
                        $amount = $moneyDetail->amount;
                    }
                } else {
                    if (in_array($hostelFee->type, [
                        HostelFee::WATER_BY_CLOCK,
                        HostelFee::ELECTRIC_BY_CLOCK,
                    ])) {
                        if ($moneyDetail) {
                            $qty = $moneyDetail->qty;
                            $amount = $moneyDetail->amount;
                        }
                    }
                }

                $feeArr[] = [
                    'id' => $hostelFee->id,
                    'is_check' => $isEnable,
                    'amount' => $amount,
                    'name' => $hostelFee->name,
                    'type' => $hostelFee->type,
                    'fee' => $hostelFee->fee,
                    'type_name' => $hostelFee->type_text,
                    'qty' => floatval($qty),
                    'room_id' => $contract->room_id,
                    'hostel_id' => $contract->room->hostel->id,
                    'start' => intval($start),
                    'end' => intval($end)
                ];

            }

            if ($currentItem) {

                return response([
                    'status' => 1,
                    'data' => [
                        'fees' => $feeArr,
                        'sum' => $item->amount,
                        'paid' => $item->pay,
                        'discount' => $item->discount,
                        'remain' => $item->remain,
                        'contract_note' => $contract->contract_note
                    ]
                ]);
            }

            return response([
                'status' => 1,
                'data' => [
                    'fees' => $feeArr,
                    'sum' => 0,
                    'paid' => 0,
                    'discount' => 0,
                    'remain' => 0,
                    'contract_note' => $contract->contract_note
                ]
            ]);

        } else {

            $hostelFees = HostelFee::query()->where('hostel_id', $room->hostel->id)->get();
            $fees = ContractFee::query()->where('contract_id', $contract->id)->pluck('fee_id')->toArray();

            foreach ($hostelFees as $hostelFee) {
                $qty = 1;
                $qtyContract = ContractFee::query()->where('fee_id', $hostelFee->id)->where('contract_id', $contract->id)->first();
                if ($qtyContract) {
                    $qty = $qtyContract->qty;
                }
                $start = 0;
                $end = 0;
                if (is_array($fees) && in_array($hostelFee->id, $fees)) {
                    $isEnable = true;
                } else {
                    $isEnable = false;
                }

                if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::WATER) {
                    $amount = 0;
                } else {
                    $amount = $hostelFee->fee;
                }

                $lastInfo = ElectricWater::query()->where('hostel_id', $contract->hostel->id)
                    ->where('room_id', $contract->room->id)
                    ->where('contract_id', $contractId)
                    ->whereBetween('date_action', [
                        $date->copy()->startOfMonth(),
                        $date->copy()->endOfMonth()
                    ])->first();

//                if (!$lastInfo) {
//                    $lastInfo = ElectricWater::query()->where('hostel_id', $contract->hostel->id)
//                        ->where('room_id', $contract->room->id)
//                        ->whereBetween('date_action', [
//                            $date->copy()->startOfMonth(),
//                            $date->copy()->endOfMonth()
//                        ])->first();
//                }

                $isCurrent = true;

                if (!$lastInfo) {
                    $isCurrent = false;

                    $lastInfo = ElectricWater::query()->where('hostel_id', $contract->hostel->id)
                        ->where('contract_id', $contract->id)
                        ->where('room_id', $contract->room->id)
                        ->where('date_action', '<', $date->copy()->startOfMonth())
                        ->orderBy('date_action', 'desc')->first();
                }


                if ($currentItem) {
                    $moneyDetail = MoneyDetail::where('money_info_id', $currentItem->id)->where('hostel_fee_id', $hostelFee->id)->first();
                    if ($moneyDetail) {


                        $info = json_decode($moneyDetail->qty, true);
                        $start = $info['start'];
                        $end = $info['end'];
                    }
                } else {

                    if ($lastInfo) {
                        if ($isCurrent) {
                            if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK) {
                                $start = $lastInfo->start_electric;
                                $end = $lastInfo->end_electric;

                            } else if ($hostelFee->type == HostelFee::WATER || $hostelFee->type == HostelFee::WATER_BY_CLOCK) {
                                $start = $lastInfo->start_water;
                                $end = $lastInfo->end_water;

                            }
                        } else {
                            if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK) {
                                $start = $lastInfo->end_electric;
                                $end = 0;

                            } else if ($hostelFee->type == HostelFee::WATER || $hostelFee->type == HostelFee::WATER_BY_CLOCK) {
                                $start = $lastInfo->end_water;
                                $end = 0;

                            }
                        }
                    } else {

                        $qty = 1;
                        $checkContract = ContractFee::query()->where('fee_id', $hostelFee->id)->where('contract_id', $contract->id)->first();

                        if ($checkContract) {

                            $qty = $checkContract->qty;
                            if ($hostelFee->type == HostelFee::ELECTRIC || $hostelFee->type == HostelFee::WATER
                                || $hostelFee->type == HostelFee::ELECTRIC_BY_CLOCK || $hostelFee->type == HostelFee::WATER_BY_CLOCK
                            ) {
                                $start = $checkContract->qty;
                                $end = $checkContract->qty;
                            }
                        }
                    }
                }

                $feeArr[] = [
                    'id' => $hostelFee->id,
                    'is_check' => $isEnable,
                    'fee' => $hostelFee->fee,
                    'amount' => $amount,
                    'name' => $hostelFee->name,
                    'type' => $hostelFee->type,
                    'type_name' => $hostelFee->type_text,
                    'qty' => floatval($qty),
                    'room_id' => $contract->room_id,
                    'hostel_id' => $contract->room->hostel->id,
                    'start' => intval($start),
                    'end' => intval($end)
                ];
            }


            return response([
                'status' => 1,
                'data' => [
                    'fees' => $feeArr,
                    'discount' => 0,
                    'sum' => 0,
                    'paid' => 0,
                    'remain' => 0,
                    'contract_note' => $contract->contract_note
                ]
            ]);
        }


        return response([
            'status' => 0,
            'message' => 'Phòng trống không thể tạo hóa đơn dịch vụ'
        ]);
    }

    /**
     * @api {post} /collect Tạo phiếu thu
     * @apiName /collect
     * @apiGroup Money
     * @apiParam {String} amount
     * @apiParam {String} room_id
     * @apiParam {String} hostel_id
     * @apiParam {String} date_action Ngày thu
     * @apiParam {String} payer Người nộp
     * @apiParam {String} name Lý do thu
     * @apiParam {String} receiver Người thu
     * @apiParam {String} type_collect_id Loại thu
     *
     * @apiParam {String} payment_method Phương thức thanh toán. 1 là tiền mặt 2 là chuyển khoản
     * @apiParam {String} note Ghi chú
     *
     * @apiDescription Api Tạo phiếu thu. Không có thì gửi các key rỗng lên
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function collect(Request $request)
    {
        $data = $request->all();

        $amount = $data['amount'];

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }

        $amount = Functions::filterInputNumber($amount);

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền phải là số'
            ]);
        }

        if (!empty($data['date_action'])) {
            $dateAction = Carbon::createFromFormat('d/m/Y', $data['date_action'])->toDateString();
        } else {
            $dateAction = Carbon::now()->toDateString();
        }

        $roomId = null;
        $hostelId = null;

        if (isset($data['room_id'])) {
            $roomId = $data['room_id'];
        }
        if (isset($data['hostel_id'])) {
            $hostelId = $data['hostel_id'];
        }

        try {
            \DB::beginTransaction();

            $transaction = Transaction::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'room_id' => $roomId,
                'date_action' => $dateAction,
                'type' => CollectSpend::COLLECT,
                'payer' => isset($data['payer']) ? $data['payer'] : null
            ]);

            $cp = CollectSpend::create([
                'amount' => $amount,
                'hostel_id' => $hostelId,
                'room_id' => $roomId,
                'note' => isset($data['note']) ? $data['note'] : null,
                'payment_method' => isset($data['payment_method']) ? $data['payment_method'] : CollectSpend::MONEY,
                'date_action' => $dateAction,
                'type' => CollectSpend::COLLECT,
                'name' => isset($data['name']) ? $data['name'] : null,
                'transaction_id' => $transaction->id,
                'payer' => isset($data['payer']) ? $data['payer'] : null,
                'receiver' => isset($data['receiver']) ? $data['receiver'] : null,
                'type_collect_id' => isset($data['type_collect_id']) ? $data['type_collect_id'] : null
            ]);

            \DB::commit();

            $files = $request->file('files');
            if (!empty($files) && is_array($files)) {
                foreach ($files as $key => $file) {
                    $name = time() . $file->getClientOriginalName();
                    $filePath = 'collect-spends/' . $cp->id . '/files/' . str_slug($name);
                    $filePath = $filePath . '.' . $file->getClientOriginalExtension();
                    \Storage::disk('s3')->put($filePath, file_get_contents($file), 'public');
                    CollectSpendFile::create([
                        'collect_spend_id' => $cp->id,
                        'name' => $file->getClientOriginalName(),
                        'file' => 'https://resident.sgp1.digitaloceanspaces.com/' . $filePath
                    ]);
                }
            }

            $user = Functions::getCurrentUser();
            $desc = '{' . optional($user)->name . '} vừa thu {' . number_format($cp->amount, 0, '.', '.') . '} với nội dung {' . $request->input('name') . '}';
            event(new LogAction([
                'type' => 'create-collect',
                'user_id' => optional($user)->id,
                'object_id' => $cp->id,
                'hostel_id' => $cp->hostel_id,
                'room_id' => $cp->room_id,
                'properties' => $cp->toArray(),
                'desc' => $desc
            ]));
        } catch (\Exception $exception) {
            \DB::rollBack();

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }


    /**
     * @api {get} /contract-deposit Lấy danh sách đặt cọc
     * @apiName /contract-deposit
     * @apiGroup Money
     * @apiParam {String} hostel_id
     * @apiParam {String} status 0-tat ca, 1- da tra coc, 2-chua tra coc
     * @apiParam {String} start_date Dạng m/Y
     * @apiParam {String} end_date Dạng m/Y
     *
     * @apiDescription Api Lấy danh sách đặt cọc
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getDeposit(Request $request)
    {
        $hostelId = $request->input('hostel_id');
        $status = $request->input('status'); //0-tat ca, 1- da tra coc, 2-chua tra coc
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $roomId = $request->input('room_id');

        if (!empty($hostelId)) {

            $contracts = CollectSpend::query()->selectRaw('collect_spends.*,
        contracts.name as contract_name, contracts.code as contract_code, contracts.reference, users.id as created_id,
        users.name, users.first_name, users.last_name')
                ->leftJoin('users', 'collect_spends.user_id', '=', 'users.id')
                ->leftJoin('contracts', 'contracts.id', '=', 'collect_spends.contract_id')
                ->where('collect_spends.is_deposit', true)
                ->where('collect_spends.hostel_id', $hostelId)
                ->where('collect_spends.type', CollectSpend::COLLECT)
                ->orderBy('collect_spends.id', 'desc');
        } else {
            $ownerId = $this->user->id;
            if ($this->user->type == User::STAFF) {
                $ownerId = $this->user->staff_owner_id;
            }

            $hostelArrs = Hostel::where('owner_id', $ownerId)->pluck('id')->toArray();
            $contracts = CollectSpend::query()->selectRaw('collect_spends.*,
        contracts.name as contract_name, contracts.code as contract_code, contracts.reference, users.id as created_id,
        users.name, users.first_name, users.last_name')
                ->leftJoin('users', 'collect_spends.user_id', '=', 'users.id')
                ->leftJoin('contracts', 'contracts.id', '=', 'collect_spends.contract_id')
                ->where('collect_spends.is_deposit', true)
                ->whereIn('collect_spends.hostel_id', $hostelArrs)
                ->where('collect_spends.type', CollectSpend::COLLECT)
                ->orderBy('collect_spends.id', 'desc');
        }

        if (!empty($roomId)) {
            $contracts = $contracts->where('collect_spends.room_id', $roomId);
        }

        if (!empty($status)) {
//            $contractItems = Contract::where('hostel_id', $hostelId);
//
//            if (!empty($roomId)) {
//                $contractItems = $contractItems->where('room_id', $roomId);
//            }

            if ($status == Contract::RETURNED_DEPOSIT) {

                // $contractItems = $contractItems->where('contracts.is_return_deposit', true);
                $contracts = $contracts->where('collect_spends.is_return_deposit', true);
            } else if ($status == Contract::NOT_RETURNED_DEPOSIT) {
                //$contractItems = $contractItems->where('contracts.is_return_deposit', false);

                $contracts = $contracts->where(function ($q) {
                    $q->where('collect_spends.is_return_deposit', false);
                    //$q->orWhereNull('collect_spends.contract_id');
                });
            } else if ($status == Contract::NEVER_RETURNED_DEPOSIT) {
                //$contractItems = $contractItems->where('contracts.is_return_deposit', false);

                $contracts = $contracts->where(function ($q) {
                    $q->where('collect_spends.is_return_deposit', 2);
                });
            }

            //   $contractItemsArr = $contractItems->pluck('id')->toArray();

            //  $contracts = $contracts->whereIn('contracts.id', $contractItemsArr);
        }

        if (!empty($startDate)) {

            try {
                $startDate = Carbon::createFromFormat('d/m/Y', '01/'.$startDate)->startOfMonth()->startOfDay()->toDateTimeString();
            } catch (\Exception $exception) {
                $startDate = Carbon::createFromFormat('d/m/Y', $startDate)->startOfDay()->toDateTimeString();
            }


            $contracts = $contracts->where('collect_spends.created_at', '>=', $startDate);
        }

        if (!empty($endDate)) {
            try {
                $endDate = Carbon::createFromFormat('d/m/Y', '01/'.$endDate)->endOfMonth()->endOfDay()->toDateTimeString();
            } catch (\Exception $exception) {
                $endDate = Carbon::createFromFormat('d/m/Y', $endDate)->endOfDay()->toDateTimeString();
            }
            $contracts = $contracts->where('collect_spends.created_at', '<=', $endDate);
        }

        //dd($contracts->toSql());
        $contracts = $contracts->get();

        $returnArr = [];

        foreach ($contracts as $contract) {
            $user = $contract->contract_name;
            if (empty($user)) {
                $deposit = RoomReservation::query()->where('room_id', optional($contract->room)->id)->first();
                if ($deposit) {
                    $user = $deposit->name;
                }
            }
            $returnArr[] = [
                'deposit' => $contract->amount,
                'is_return_deposit' => $contract->is_return_deposit,
                'code' => $contract->contract_code,
                'room' => !empty($contract->room) ? $contract->room->name : null,
                'user' => $user,
                'created_at' => $contract->created_at->format('d/m/Y'),
                'created_by' => [
                    'id' => $contract->created_id,
                    'name' => !empty($contract->name) ? $contract->name : $contract->first_name . ' ' . $contract->last_name
                ]
            ];
        }

        return response([
            'status' => 1,
            'data' => $returnArr
        ]);
    }

    /**
     * @api {get} /current-deposit Lấy danh sách đặt cọc đang giữ
     * @apiName /current-deposit
     * @apiGroup Money
     * @apiParam {String} hostel_id
     * @apiParam {String} room_id
     * @apiParam {String} limit
     * @apiParam {String} offset
     * @apiParam {String} type 1 la coc giu cho, 2 la coc hop dong
     * @apiParam {String} start_date Dạng m/Y
     * @apiParam {String} end_date Dạng m/Y
     *
     * @apiDescription Api Lấy danh sách đặt cọc đang giữ
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getCurrentDeposit(Request $request)
    {
        $hostelId = $request->input('hostel_id');
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $roomId = $request->input('room_id');
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);

        $deposits = Deposit::query()
            ->with([
                'hostel',
                'room',
                'reserve',
                'contract'
            ])
            ->where(function ($q) {
                $q->orWhereHas('reserve');
                $q->orWhereHas('contractValid');
            })
            ->when(!empty($request->input('type')), function ($q) {
                $type = \request()->input('type');
                if ($type == 2) {
                    $q->has('contractValid');
                } else {
                    $q->doesntHave('contract');
                }
            });

        if (!empty($hostelId)) {
            $deposits = $deposits->where('hostel_id', $hostelId);
        } else {
            $ownerId = $this->user->id;
            $hostelArrs = Hostel::query()
                ->where('owner_id', $ownerId)
                ->pluck('id')
                ->toArray();
            if ($this->user->type == User::STAFF) {
                $ownerId = $this->user->staff_owner_id;
                $hostelArrs = Functions::getHostelArrStaffApi($this->user);
            }

            $deposits = $deposits->whereIn('hostel_id', $hostelArrs);
        }

        if (!empty($roomId)) {
            $deposits = $deposits->where('room_id', $roomId);
        }

        if (!empty($startDate)) {

            $startDate = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->startOfMonth()->startOfDay()->toDateTimeString();
            $deposits = $deposits->where('date_action', '>=', $startDate);
        }

        if (!empty($endDate)) {
            $endDate = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->endOfMonth()->endOfDay()->toDateTimeString();
            $deposits = $deposits->where('date_action', '<=', $endDate);
        }

        $deposits = $deposits->limit($limit)->offset($offset)->get();


        $returnArr = [];

        foreach ($deposits as $deposit) {
            $createdBy = null;
            $user = null;
            if ($deposit->contract) {
                $user = $deposit->contract->name;
                if ($deposit->contract->user) {
                    $createdBy = [
                        'id' => $deposit->contract->user->id,
                        'name' => $deposit->contract->user->name_text
                    ];

                }

            } else if ($deposit->reserve) {
                $user = $deposit->reserve->name;
                if ($deposit->reserve->user) {
                    $createdBy = [
                        'id' => $deposit->reserve->user->id,
                        'name' => $deposit->reserve->user->name_text
                    ];
                }
            }
            $bedArr = null;
            $reserve = $deposit->reserve;
            if ($reserve) {
                $bed = $reserve->bed;
                if ($bed) {
                    $bedArr = [
                        'id' => $bed->id,
                        'name' => $bed->name
                    ];
                }
            }

            $returnArr[] = [
                'id' => $deposit->id,
                'deposit' => $deposit->amount,
                'is_contract' => $deposit->reserve ? false : true,
                'room' => !empty($deposit->room) ? $deposit->room->name : null,
                'room_id' => !empty($deposit->room) ? $deposit->room->id : null,
                'room_name' => !empty($deposit->room) ? $deposit->room->name : null,
                'hostel_id' => !empty($deposit->hostel) ? $deposit->hostel->id : null,
                'hostel_name' => !empty($deposit->hostel) ? $deposit->hostel->name : null,
                'hostel_type_rent' => !empty($deposit->hostel) ? $deposit->hostel->type_rent : null,
                'user' => $user,
                'created_at' => !empty($deposit->date_action) ? $deposit->date_action->format('d/m/Y') : null,
                'created_by' => $createdBy,
                'bed' => $bedArr
            ];
        }

        return response([
            'status' => 1,
            'data' => $returnArr
        ]);
    }


    /**
     * @api {get} /print-money-info Download pdf hóa đơn
     * @apiName print-money-info
     * @apiGroup Money
     * @apiDescription Api Download pdf hóa đơn
     * @apiParam {String} money_info_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function printBill(Request $request)
    {
        $id = $request->input('money_info_id');
        $isZalo = $request->input('is_zalo');
        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }

        if (!empty($isZalo)) {
            $moneyInfo = MoneyInfo::find($id);
            if ($moneyInfo) {
                $contract = $moneyInfo->contract;
                if ($contract) {
                    $amount = $moneyInfo->remain;
                    if ($amount <= 0) {
                        return response([
                            'status' => 0,
                            'message' => 'Hóa đơn đã thanh toán hết nên không thể gửi nhắc nợ'
                        ]);
                    }
                    $roomName = $contract->room->name;
                    $hostelName = $contract->hostel->name;
                    $phone = $contract->phone;
                    $customerName = $contract->name;

                    $invoicePath = url('bill/print?token=' . $token, ['id' => $id]);
                    $invoicePathPrint = str_replace('https://itro.vn/bill/', '', $invoicePath);

                    $phone = ltrim($phone, '0');
                    $phone = '84' . $phone;
                    $response = Functions::sendMessageInvoiceZns([
                        'phone' => $phone,
                        'room_name' => $roomName,
                        'amount' => $amount,
                        'invoice_path' => $invoicePathPrint,
                        'customer_name' => $customerName,
                        'hostel_name' => $hostelName,
                        'hostel_id' => $contract->hostel->id,
                        'room_id' => $contract->room->id,
                    ]);
                    if(empty($response)) {
                       return response([
                           'status' => 0,
                           'message' => 'Bạn đã hết số lượt gửi zalo'
                       ]);
                    }
                }
            }
        }

        return response([
            'status' => 1,
            'data' => url('bill/print?token=' . $token, ['id' => $id])
        ]);
    }

    /**
     * @api {get} /print-end-contract Print hoa don thanh ly HD
     * @apiName print-end-contract
     * @apiGroup Money
     * @apiDescription Api Print hoa don thanh ly HD
     * @apiParam {String} contract_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function printEndContract(Request $request)
    {
        $id = $request->input('contract_id');
        $isReturnMoneyInfo = $request->input('is_return_money_info', 0);
        $isReturnDeposit = $request->input('is_return_deposit', 0);
        $dateEndContract = $request->input('date_end_contract');
        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }

        return response([
            'status' => 1,
            'data' => url('bill/print-end-contract?token=' . $token . '&is_return_money_info=' . $isReturnMoneyInfo .
                '&is_return_deposit=' . $isReturnDeposit . '&date_end_contract=' . $dateEndContract, ['id' => $id])
        ]);
    }

    /**
     * @api {get} /print-money-info-month Download pdf hóa đơn theo tháng
     * @apiName print-money-info-month
     * @apiGroup Money
     * @apiDescription Api Download pdf hóa đơn theo tháng
     * @apiParam {String} money_info_id
     * @apiParam {String} contract_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function printAllBill(Request $request)
    {
        $id = $request->input('money_info_id');
        $contractId = $request->input('contract_id');
        $isZalo = $request->input('is_zalo');
        $month = $request->input('month');
        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }

        if (!empty($month)) {
            $invoicePath = url('bill/print-all?month=' . $month . '&token=' . $token, [
                'id' => $id,
                'contractId' => $contractId
            ]);
        } else {
            $invoicePath = url('bill/print-all?token=' . $token, ['id' => $id, 'contractId' => $contractId]);
        }

        if (!empty($isZalo)) {
            $moneyInfo = MoneyInfo::find($id);
            if ($moneyInfo) {
                $contract = $moneyInfo->contract;
                if ($contract) {
                    $amount = MoneyInfo::query()
                        ->when(!empty($month), function ($q) use ($month) {
                            $date = Carbon::createFromFormat('d/m/Y', '01/' . $month);
                            $q->whereBetween('date_action', [
                                $date->copy()->startOfMonth()->startOfDay(),
                                $date->copy()->endOfMonth()->endOfDay()
                            ]);
                        }, function ($q) use ($moneyInfo) {
                            $q->whereBetween('date_action', [
                                $moneyInfo->date_action->startOfMonth()->startOfDay(),
                                $moneyInfo->date_action->endOfMonth()->endOfDay()
                            ]);
                        })
                        ->where('contract_id', $contractId)
                        ->sum('remain');
                    if ($amount <= 0) {
                        return response([
                            'status' => 0,
                            'message' => 'Hóa đơn đã thanh toán hết nên không thể gửi nhắc nợ'
                        ]);
                    }
                    $roomName = $contract->room->name;
                    $hostelName = $contract->hostel->name;
                    $phone = $contract->phone;
                    $customerName = $contract->name;

                    $invoicePathPrint = str_replace('https://itro.vn/bill/', '', $invoicePath);

                    $phone = ltrim($phone, '0');
                    $phone = '84' . $phone;
                    $responseMessage =  Functions::sendMessageInvoiceZns([
                        'phone' => $phone,
                        'room_name' => $roomName,
                        'amount' => $amount,
                        'invoice_path' => $invoicePathPrint,
                        'customer_name' => $customerName,
                        'hostel_name' => $hostelName,
                        'hostel_id' => $contract->hostel->id,
                        'room_id' => $contract->room->id
                    ]);
                    if (empty($responseMessage)) {

                        return response([
                            'status' => 0,
                            'message' => 'Bạn đã hết số lượt gửi zalo'
                        ]);
                    }
                }
            }
        }

        return response([
            'status' => 1,
            'data' => $invoicePath
        ]);
    }

    /**
     * @api {get} /print-money-info-room-service Download pdf hóa đơn theo tháng phòng và dịch vụ
     * @apiName print-money-info-room-service
     * @apiGroup Money
     * @apiDescription Api Download pdf hóa đơn theo tháng phòng và dịch vụ
     * @apiParam {String} month
     * @apiParam {String} contract_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function printAllBillRoomService(Request $request)
    {
        $contractId = $request->input('contract_id');
        $month = $request->input('month');
        $isZalo = $request->input('is_zalo');

        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }

        if (!empty($isZalo)) {

            $contract = Contract::find($contractId);
            if ($contract) {
                $dateCarbon = Carbon::createFromFormat('d/m/Y', '01/' . $month);
                $items = MoneyInfo::query()
                    ->where(function ($q) use ($dateCarbon) {
                        $q->orWhere(function ($q2) use ($dateCarbon) {
                            $q2->where('type', MoneyInfo::VOUCHER_SERVICE)
                                ->whereBetween('date_action', [
                                    $dateCarbon->copy()->subMonth()->startOfMonth()->startOfDay(),
                                    $dateCarbon->copy()->subMonth()->endOfMonth()->endOfDay()
                                ]);
                        });
                        $q->orWhere(function ($q2) use ($dateCarbon) {
                            $q2->whereIn('type', [MoneyInfo::VOUCHER_ROOM_PRICE, MoneyInfo::VOUCHER_CONTRACT])
                                ->whereBetween('date_action', [
                                    $dateCarbon->copy()->startOfMonth()->startOfDay(),
                                    $dateCarbon->copy()->endOfMonth()->endOfDay()
                                ]);
                        });
                    })
                    ->when(!empty($contractId), function ($q) use ($contractId) {
                        $q->where('contract_id', $contractId);
                    });
                $amount = $items->sum('remain');
                if ($amount <= 0) {
                    return response([
                        'status' => 0,
                        'message' => 'Hóa đơn đã thanh toán hết nên không thể gửi nhắc nợ'
                    ]);
                }

                $roomName = $contract->room->name;
                $hostelName = $contract->hostel->name;
                $phone = $contract->phone;
                $customerName = $contract->name;

                $invoicePath = url('bill/print-m-r-s?contract_id=' . $contractId . '&month=' . $month . '&token=' . $token);
                $invoicePathPrint = str_replace('https://itro.vn/bill/', '', $invoicePath);

                $phone = ltrim($phone, '0');
                $phone = '84' . $phone;
                $res = Functions::sendMessageInvoiceZns([
                    'phone' => $phone,
                    'room_name' => $roomName,
                    'amount' => $amount,
                    'invoice_path' => $invoicePathPrint,
                    'customer_name' => $customerName,
                    'hostel_name' => $hostelName,
                    'hostel_id' => $contract->hostel->id,
                    'room_id' => $contract->room->id
                ]);

                if (empty($res)) {

                    return response([
                        'status' => 0,
                        'message' => 'Bạn đã hết số lượt gửi zalo'
                    ]);
                }
            }

        }


        return response([
            'status' => 1,
            'data' => url('bill/print-money-info-room-service?contract_id=' . $contractId . '&month=' . $month . '&token=' . $token)
        ]);

    }

    /**
     * @api {post} /send-zalo-unpaid Gửi zalo hóa đơn chưa thanh toán
     * @apiName send-zalo-unpaid
     * @apiGroup Money
     * @apiDescription Api Gửi zalo hóa đơn chưa thanh toán
     * @apiParam {String} hostel_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function sendZaloUnpaid(Request $request)
    {
        $owner = $this->user;
        if ($this->user->type == User::STAFF) {
            $owner = $this->user->owner;
        }
        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }
        $hostelId = $request->input('hostel_id');

        $contracts = Contract::query()
            ->with([
                'room',
                'hostel'
            ])
            ->where('status', '<>', Contract::LIQUIDATED)
            ->whereHas('hostel', function ($q) use ($owner) {
                $q->where('hostels.owner_id', $owner->id);
            })
            ->when(!empty($hostelId), function ($q) use ($hostelId) {
                $q->where('hostel_id', $hostelId);
            })
            ->get();

        foreach ($contracts as $contract) {
            $id = $contract->id;
            $items = MoneyInfo::query()
                ->where('remain', '>', 0)
                ->when(!empty($id), function ($q) use ($contract) {
                    $q->where('contract_id', $contract->id);
                });
            $amount = $items->sum('remain');
            if ($amount <= 0) {
                continue;
            }
            $roomName = $contract->room->name;
            $hostelName = $contract->hostel->name;
            $phone = $contract->phone;
            $customerName = $contract->name;

            $invoicePath = url('bill/print-a-c-u?token=' . $token, ['id' => $id]);
            $invoicePathPrint = str_replace('https://itro.vn/bill/', '', $invoicePath);

            $phone = ltrim($phone, '0');
            $phone = '84' . $phone;
            $res = Functions::sendMessageInvoiceZns([
                'phone' => $phone,
                'room_name' => $roomName,
                'amount' => $amount,
                'invoice_path' => $invoicePathPrint,
                'customer_name' => $customerName,
                'hostel_name' => $hostelName,
                'hostel_id' => $contract->hostel->id,
                'room_id' => $contract->room->id
            ]);
            if (empty($res)) {

                return response([
                    'status' => 0,
                    'message' => 'Bạn đã hết số lượt gửi zalo'
                ]);
            }
        }

        return response([
            'status' => 1
        ]);
    }

    public function printAllBillContractUnpaid(Request $request)
    {
        $id = $request->input('contract_id');
        $month = $request->input('month');
        $isZalo = $request->input('is_zalo');

        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }

        if (!empty($isZalo)) {

            $contract = Contract::find($id);
            if ($contract) {

                $items = MoneyInfo::query()
                    ->when(!empty($month), function ($q) use ($month) {
                        $dateCarbon = Carbon::createFromFormat('d/m/Y', '01/' . $month);
                        $q->whereBetween('date_action', [
                            $dateCarbon->copy()->subMonth()->startOfMonth()->startOfDay(),
                            $dateCarbon->copy()->subMonth()->endOfMonth()->endOfDay()
                        ]);
                    })
                    ->where('remain', '>', 0)
                    ->when(!empty($id), function ($q) use ($id) {
                        $q->where('contract_id', $id);
                    });
                $amount = $items->sum('remain');
                if ($amount <= 0) {
                    return response([
                        'status' => 0,
                        'message' => 'Hóa đơn đã thanh toán hết nên không thể gửi nhắc nợ'
                    ]);
                }

                $roomName = $contract->room->name;
                $hostelName = $contract->hostel->name;
                $phone = $contract->phone;
                $customerName = $contract->name;

                $invoicePath = url('bill/print-a-c-u?month=' . $month . '&token=' . $token, ['id' => $id]);
                $invoicePathPrint = str_replace('https://itro.vn/bill/', '', $invoicePath);

                $phone = ltrim($phone, '0');
                $phone = '84' . $phone;
                $res = Functions::sendMessageInvoiceZns([
                    'phone' => $phone,
                    'room_name' => $roomName,
                    'amount' => $amount,
                    'invoice_path' => $invoicePathPrint,
                    'customer_name' => $customerName,
                    'hostel_name' => $hostelName,
                    'hostel_id' => $contract->hostel->id,
                    'room_id' => $contract->room->id
                ]);
                if (empty($res)) {

                    return response([
                        'status' => 0,
                        'message' => 'Bạn đã hết số lượt gửi zalo'
                    ]);
                }
            }

        }


        if (!empty($month)) {
            return response([
                'status' => 1,
                'data' => url('bill/print-all-contract-unpaid?month=' . $month . '&token=' . $token, ['id' => $id])
            ]);
        }

        return response([
            'status' => 1,
            'data' => url('bill/print-all-contract-unpaid?token=' . $token, ['id' => $id])
        ]);
    }

    /**
     * @api {get} /list-type-spend Lấy danh sách loại phiếu chi
     * @apiName list-type-spend
     * @apiGroup Money
     * @apiDescription Api Lấy danh sách loại phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function getTypeSpend(Request $request)
    {
        $ownerId = $this->user->id;
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }
        $items = TypeSpend::query()->where('owner_id', $ownerId)->get();

        if ($items->count() == 0) {
            TypeSpend::query()->create([
                'owner_id' => $ownerId,
                'name' => 'Tiền Nhà',
                'is_default' => TypeSpend::TIEN_NHA,
            ]);
            TypeSpend::query()->create([
                'owner_id' => $ownerId,
                'name' => 'Tiền Điện',
                'is_default' => TypeSpend::TIEN_DIEN,
            ]);

            TypeSpend::query()->create([
                'owner_id' => $ownerId,
                'name' => 'Tiền Nước',
                'is_default' => TypeSpend::TIEN_NUOC,
            ]);
        }

        $items = TypeSpend::query()->where('owner_id', $ownerId)->get();

        return response([
            'status' => 1,
            'message' => 'Success',
            'data' => $items,
        ]);
    }

    /**
     * @api {get} /stat Lấy thông tin tkkd
     * @apiName stat
     * @apiGroup Money
     * @apiDescription Api Lấy thông tin tkkd
     * @apiParam {String} hostel_id
     * @apiParam {String} start_date dạng m/Y
     * @apiParam {String} hostel_id
     * @apiParam {String} end_date dạng m/Y
     * @apiParam {String} room_id
     * @apiParam {String} limit
     * @apiParam {String} offset
     * @apiParam {String} type_spend
     * @apiParam {String} type_collect[]
     * @apiParam {String} type
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getStat(Request $request)
    {
        $ownerId = $this->user->id;
        $user = $this->user;
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);
        $hostel = $request->input('hostel_id');
        $roomId = $request->input('room_id');
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $type = $request->input('type');
        $typeSpend = $request->input('type_spend');
        $typeCollect = $request->input('type_collect');
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }

        $hostelArrs = Hostel::query()->where('owner_id', $ownerId)
            ->pluck('id')
            ->toArray();
        if ($this->user->type == User::STAFF) {
            $hostelArrs = Functions::getHostelArrStaffApi($this->user);
        }

        $items = StatisticLog::query()->select(DB::raw('statistic_logs.*, CONCAT(month,"/", year) AS date'))
            ->where('statistic_logs.amount', '>', 0)
            ->with([
                'hostel' => function ($q) {
                    $q->select('id', 'name');
                },
                'room' => function ($q) {
                    $q->select('id', 'name');
                },
                'collectSpend' => function ($q) {
                    $q->select('id', 'code', 'type_collect_id', 'type_purpose');
                },
                'contract' => function ($q) {
                    $q->select('id', 'code');
                }
            ])
            ->where(function ($q) {
                $q->orWhereNull('collect_spend_id');
                $q->orWhere(function ($q) {
                    $q->has('collectSpend');
                });
            })
            ->leftJoin('collect_spends', 'statistic_logs.collect_spend_id', '=', 'collect_spends.id')
            ->where(function ($q) use ($hostelArrs, $ownerId, $user) {
                $q->when($user->type == User::OWNER, function ($q) use ($hostelArrs, $ownerId) {
                    $q->orWhereIn('statistic_logs.hostel_id', $hostelArrs);
                    $q->orWhere('statistic_logs.owner_id', $ownerId);
                }, function ($q) use ($hostelArrs) {
                    $q->whereIn('statistic_logs.hostel_id', $hostelArrs);
                });
            });


        if (!empty($hostel)) {
            $items = $items->where('statistic_logs.hostel_id', $hostel);
        }

        if (!empty($roomId)) {
            $items = $items->where('statistic_logs.room_id', $roomId);
        }

        if (!empty($startDate)) {
            $startDate = Carbon::createFromFormat('d/m/Y', '1/' . $startDate)->startOfMonth();
            $startMonth = $startDate->copy()->month;
            $startYear = $startDate->copy()->year;
            $items = $items->where('statistic_logs.month', '>=', $startMonth)
                ->where('statistic_logs.year', '>=', $startYear);
        }

        if (!empty($endDate)) {
            $endDate = Carbon::createFromFormat('d/m/Y', '1/' . $endDate)->endOfMonth();
            $endMonth = $endDate->copy()->month;
            $endYear = $endDate->copy()->year;
            $items = $items->where('statistic_logs.month', '<=', $endMonth)
                ->where('statistic_logs.year', '<=', $endYear);
        }

        if (!empty($typeCollect) || !empty($typeSpend)) {

            $items = $items->whereHas('collectSpend', function ($q) use ($typeCollect, $typeSpend) {
                $q->where(function ($q) use ($typeCollect, $typeSpend) {
                    if (!empty($typeCollect)) {
                        $q->orWhereIn('type_collect_id', $typeCollect);
                    }

                    if (!empty($typeSpend)) {
                        $q->orWhereIn('type_purpose', $typeSpend);
                    }
                });
            });
        }


        $itemsCollect = clone $items;
        $itemsSpend = clone $items;
        $collect = $itemsCollect->where('statistic_logs.type', CollectSpend::COLLECT)->sum('statistic_logs.amount');
        $spend = $itemsSpend->where('statistic_logs.type', CollectSpend::SPEND)->sum('statistic_logs.amount');
        $items = $items->limit($limit)->offset($offset)->get()
            ->map(function ($item) {
                $arr = $item->toArray();
                if ($item->collectSpend) {
                    $arr['type_collect'] = $item->collectSpend->typeCollect;
                    $arr['type_spend'] = $item->collectSpend->typespend;
                }

                return $arr;
            });

        return response([
            'status' => 1,
            'data' => [
                'stat' => [
                    'collect' => $collect,
                    'spend' => $spend
                ],
                'items' => $items
            ]
        ]);
    }

    /**
     * @api {get} /stat-2 Lấy thông tin tkkd cho bản mới
     * @apiName stat-2
     * @apiGroup Money
     * @apiDescription Api Lấy thông tin tkkd
     * @apiParam {String} hostel_id
     * @apiParam {String} start_date dạng m/Y
     * @apiParam {String} end_date dạng m/Y
     * @apiParam {String} room_id
     * @apiParam {String} limit
     * @apiParam {String} offset
     * @apiParam {String} type_spend
     * @apiParam {String} type_collect[]
     * @apiParam {String} type
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getStat2(Request $request)
    {
        $ownerId = $this->user->id;
        $hostel = $request->input('hostel_id');
        $roomId = $request->input('room_id');
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
        $type = $request->input('type');
        $typeSpend = $request->input('type_spend');
        $typeCollect = $request->input('type_collect');
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }

        $hostelArrs = Hostel::query()->where('owner_id', $ownerId)
            ->pluck('id')
            ->toArray();
        $items = StatisticLog::query()->select(DB::raw('statistic_logs.*'))
            ->with([
                'hostel' => function ($q) {
                    $q->select('id', 'name');
                },
                'room' => function ($q) {
                    $q->select('id', 'name');
                },
                'collectSpend' => function ($q) {
                    $q->select('id', 'code', 'type_collect_id');
                },
                'contract' => function ($q) {
                    $q->select('id', 'code');
                }
            ])
            ->where(function ($q) {
                $q->orWhereNull('collect_spend_id');
                $q->orWhere(function ($q) {
                    $q->has('collectSpend');
                });
            })
            ->leftJoin('collect_spends', 'statistic_logs.collect_spend_id', '=', 'collect_spends.id')
            ->where(function ($q) use ($hostelArrs, $ownerId) {
                $q->orWhereIn('statistic_logs.hostel_id', $hostelArrs);
                $q->orWhere('statistic_logs.owner_id', $ownerId);
            });


        if (!empty($hostel)) {
            $items = $items->where('statistic_logs.hostel_id', $hostel);
        }

        if (!empty($roomId)) {
            $items = $items->where('statistic_logs.room_id', $roomId);
        }
        if (!empty($typeCollect) || !empty($typeSpend)) {

            $items = $items->whereHas('collectSpend', function ($q) use ($typeCollect, $typeSpend) {
                $q->where(function ($q) use ($typeCollect, $typeSpend) {
                    if (!empty($typeCollect)) {
                        $q->orWhereIn('type_collect_id', $typeCollect);
                    }

                    if (!empty($typeSpend)) {
                        $q->orWhereIn('type_purpose', $typeSpend);
                    }
                });
            });
        }

        $itemsCollect = clone $items;
        $itemsSpend = clone $items;
        $startDate = Carbon::createFromFormat('d/m/Y', $startDate);
        $endDate = Carbon::createFromFormat('d/m/Y', $endDate);

        $responseArr = [];
        $iteDate = $startDate->copy();
        $diffs = $startDate->copy()->diffInDays($endDate);
        for ($i = 1; $i <= $diffs; $i++) {
            $itemDate = clone $items;
            $itemDate = $itemDate->whereBetween('statistic_logs.date_action', [
                $iteDate->copy()->startOfDay(),
                $iteDate->copy()->endOfDay()
            ]);
            $responseArr[] = [
                'date' => $iteDate->copy()->format('d/m/Y'),
                'items' => $itemDate->get()
            ];
            $iteDate->addDay();
        }

        $month = $startDate->copy()->month;
        $year = $startDate->copy()->year;


        $collect = $itemsCollect->where('statistic_logs.type', CollectSpend::COLLECT)
            ->where('month', $month)
            ->where('year', $year)
            ->sum('statistic_logs.amount');
        $spend = $itemsSpend->where('statistic_logs.type', CollectSpend::SPEND)
            ->where('month', $month)
            ->where('year', $year)
            ->sum('statistic_logs.amount');
        $items = $items->get();

        return response([
            'status' => 1,
            'data' => [
                'stat' => [
                    'collect' => $collect,
                    'spend' => $spend
                ],
                'items' => $items
            ]
        ]);
    }

    /**
     * @api {get} /print-all-unpaid-contract-by-hostel In tất cả hóa đơn chưa thanh toán của nhà trọ
     * @apiName print-all-unpaid-contract-by-hostel
     * @apiGroup Money
     * @apiDescription Api In danh sách chưa thanh toán của nhà trọ
     * @apiParam {String} hostel_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function printAllUnpaidContractByHostel(Request $request)
    {
        $id = $request->input('hostel_id');
        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }

        return response([
            'status' => 1,
            'message' => 'Success!',
            'data' => url('bill/print-all-unpaid-contract-by-hostel?token=' . $token, ['id' => $id]),
        ]);
    }

    /**
     * @api {get} /send-all-unpaid-by-hostel Gửi tin nhắn thông báo hóa đơn chưa thanh toán cho phòng/giường
     * @apiName send-all-unpaid-by-hostel
     * @apiGroup Money
     * @apiDescription Api Gửi hóa đơn chưa thanh toán cho phòng/giường theo Nhà trọ
     * @apiParam {String} hostel_id
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     */

    public function sendAllUnpaidByHostel(Request $request)
    {
        $id = $request->input('hostel_id');
        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }
        $hostel = Hostel::find($id);

        $fromUser = $this->user->id;

        if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {
            $hostelRoomUnPaid = MoneyInfo::where('hostel_id', $id)->where('remain', '>', 0)->pluck('room_id')->toArray();
            $conversations = Conversation::whereIn('room_id', array_unique($hostelRoomUnPaid))
                ->whereNotNull('hostel_id')
                ->get();

            if ($conversations->count() <= 0) {
                return response([
                    'status' => 0,
                    'message' => 'Dữ liệu không hợp lệ'
                ]);
            }

            foreach ($conversations as $conversation) {
                $content = 'Danh sách hóa đơn chưa thanh toán: ' . url('bill/print-all-unpaid-contract-by-hostel-room?token=' . $token, [
                        'id' => $id,
                        'room_id' => $conversation->room_id
                    ]);
                $message = Message::create([
                    'content' => $content,
                    'conversation_id' => $conversation->id,
                    'type' => Message::TYPE_TEXT,
                    'from' => $fromUser
                ]);


                $conversation->update([
                    'last_message_id' => $message->id,
                    'last_message_time' => Carbon::now()->toDateTimeString()
                ]);
                $messageArr = $message->toArray();
                $content = $message->content;
                $userOnlineArr = [];

                if (isset($usersChannel['result'])) {
                    if (isset($usersChannel['result']['users'])) {
                        foreach ($usersChannel['result']['users'] as $item) {
                            $userIdOnline = $item['id'];
                            $userOnlineArr[] = $userIdOnline;
                        }
                    }
                }


                $membersArr = \DB::table('user_conversations')->where('conversation_id', $conversation->id)->pluck('user_id')->toArray();

                foreach ($membersArr as $userId) {


                    $q = \DB::table('user_conversations')
                        ->where('conversation_id', $conversation->id)
                        ->where('user_id', $userId);

                    if (in_array($userId, $userOnlineArr)) {
                        $q->update([
                            'is_read_last_message' => 1
                        ]);
                    } else {
                        $q->update([
                            'is_read_last_message' => 0
                        ]);
                    }

                    if ($message->type == Message::TYPE_IMAGE || $message->type == Message::TYPE_SYSTEM) {
                        if ($userId == $fromUser) {
                            if ($message->type == Message::TYPE_IMAGE) {
                                $content = 'Bạn đã gửi một ảnh';
                            } else {
                                $content = 'Bạn ' . $content;
                            }
                        } else {
                            $fromUser = $message->fromUser;
                            if ($fromUser) {
                                if ($message->type == Message::TYPE_IMAGE) {
                                    $content = $fromUser->name_text . ' đã gửi một ảnh';
                                } else {
                                    $content = $fromUser->name_text . ' ' . $content;
                                }
                            }
                        }

                    }

                    $messageArr['content'] = $content;


                    $this->pusher->trigger('chat-' . $userId, 'new-message', $messageArr);

                    dispatch(new SendNotificationMessage($userId, $messageArr));
                }
            }
        }

        if ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
            $hostelRoomUnPaidUsers = MoneyInfo::where('hostel_id', $id)->where('remain', '>', 0)->groupBy('user_id')->get();
            foreach ($hostelRoomUnPaidUsers as $hostelRoomUnPaidUser) {
                $contractId = $hostelRoomUnPaidUser->contract_id;
                $content = 'Hóa đơn chưa thanh toán: ' . url('bill/print-all-contract-unpaid?token=' . $token, ['id' => $contractId]);
                dispatch(new SendMessageBot($content, $hostelRoomUnPaidUser->user_id, $fromUser));
            }
        }

        return response([
            'status' => 1,
            'message' => 'Thành công',
        ]);
    }

    public function sendAllUnpaidByHostel2(Request $request)
    {
        $id = $request->input('hostel_id');
        $token = $this->user->token;
        if (empty($token)) {
            $token = uniqid();
            $this->user->token = $token;
            $this->user->save();
        }
        if (empty($id)) {
            if ($this->user->type == User::STAFF) {
                $hostelArrs = Functions::getHostelArrStaffApi($this->user);
            } else {
                $hostelArrs = Hostel::query()
                    ->where('owner_id', $this->user->id)
                    ->pluck('id')
                    ->toArray();
            }

            foreach ($hostelArrs as $hostelArr) {
                $request->request->remove('hostel_id');
                $request->request->add([
                    'hostel_id' => $hostelArr
                ]);
                $this->sendAllUnpaidByHostel2($request);

            }
            return response([
                'status' => 1,
                'message' => 'Thành công'
            ]);
        }

        $hostel = Hostel::find($id);

        $fromUser = $this->user->id;

        if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {
            $hostelRoomUnPaid = MoneyInfo::where('hostel_id', $id)
                ->where('remain', '>', 0)
                ->pluck('room_id')
                ->toArray();
            $conversations = \App\Models_v2\Conversation::query()->whereIn('room_id', array_unique($hostelRoomUnPaid))
                ->get();

            if ($conversations->count() <= 0) {
                return response([
                    'status' => 0,
                    'message' => 'Dữ liệu không hợp lệ'
                ]);
            }
            //dd($conversations->pluck('id')->toArray());


            foreach ($conversations as $conversation) {
                $content = 'Danh sách hóa đơn chưa thanh toán: ' . url('bill/print-all-unpaid-contract-by-hostel-room?token=' . $token, [
                        'id' => $id,
                        'room_id' => $conversation->room_id
                    ]);
                $content = strip_tags($content, '<p><a>');
                dispatch(new SendMessageV2($conversation->id, $content, $this->user->id));
            }
        } else if ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
            $hostelRoomUnPaidUsers = MoneyInfo::where('hostel_id', $id)->where('remain', '>', 0)->groupBy('user_id')->get();
            foreach ($hostelRoomUnPaidUsers as $hostelRoomUnPaidUser) {
                $contractId = $hostelRoomUnPaidUser->contract_id;
                $content = 'Hóa đơn chưa thanh toán: ' . url('bill/print-all-contract-unpaid?token=' . $token, ['id' => $contractId]);
                $content = strip_tags($content, '<p><a>');
                dispatch(new SendMessageBotV2($content, $hostelRoomUnPaidUser->user_id, $fromUser))->onConnection('redis');
                // dispatch(new SendMessageBotV2($content, $hostelRoomUnPaidUser->user_id, $fromUser))->onConnection('redis');
            }
        }

        return response([
            'status' => 1,
            'message' => 'Thành công',
        ]);
    }

    /**
     * @api {get} /get-type-collect Lấy danh sách các loại thu
     * @apiName get-type-collect
     * @apiGroup Money
     * @apiDescription Api Lấy danh sách các loại thu
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getTypeCollect(Request $request)
    {
        $ownerId = $this->user->id;
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }

        $items = TypeCollect::query()
            ->where('owner_id', $ownerId)
            ->get();

        return response([
            'status' => 1,
            'data' => $items
        ]);
    }

    /**
     * @api {post} /update-collect Cập nhật phiếu thu
     * @apiName update-collect
     * @apiGroup Money
     * @apiParam {Number} amount Số tiền
     * @apiParam {String} date_action Ngày thu
     * @apiParam {String} id Id phiếu
     * @apiParam {String} name Tên phiếu
     * @apiParam {String} receiver Người thu
     * @apiParam {String} payer Người nộp
     * @apiParam {String} payment_method Hình thức
     * @apiParam {String} note Ghi chú
     * @apiParam {String} type_collect_id Loại phiếu thu
     *
     * @apiDescription Api Cập nhật phiếu thu
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function updateCollect(Request $request)
    {
        $data = $request->all();

        $amount = $data['amount'];

        if (empty($amount)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống số tiền'
            ]);
        }

        $amount = Functions::filterInputNumber($amount);
        $data['amount'] = $amount;

        if (!is_numeric($amount)) {
            return response([
                'status' => 0,
                'message' => 'Số tiền phải là số'
            ]);
        }

        if (!empty($data['date_action'])) {
            $data['date_action'] = Carbon::createFromFormat('d/m/Y', $data['date_action'])->toDateString();
        } else {
            $data['date_action'] = Carbon::now()->toDateString();
        }


        try {
            \DB::beginTransaction();

            $collectSpend = CollectSpend::find($data['id']);

            if (!$collectSpend) {
                return response([
                    'status' => 0,
                    'message' => 'Dữ liệu không hợp lệ'
                ]);
            }

            $roomId = $collectSpend->room_id;
            $hostelId = $collectSpend->hostel_id;

            $collectSpend->update($data);

            $dateAction = $collectSpend->date_action;
            if (!empty($dateAction)) {
                $month = $collectSpend->date_action->month;
                $year = $collectSpend->date_action->year;
                StatisticLog::query()->where('collect_spend_id', $collectSpend->id)

                    ->update([
                        'month' => $month,
                        'year' => $year
                    ]);
            }

            $transactionId = $collectSpend->transaction_id;
            $transaction = Transaction::find($transactionId);

            if ($transaction) {
                $transaction->amount = $amount;
                $transaction->save();
            }

            $paid = Transaction::query()->where('money_info_id', $transaction->money_info_id)->sum('amount');
            $moneyInfo = MoneyInfo::find($transaction->money_info_id);
            if ($moneyInfo) {
                $moneyInfo->pay = $paid;
                $moneyInfo->remain = $moneyInfo->amount - $moneyInfo->discount - $paid;
                $moneyInfo->save();
            }

            if (isset($data['receiver'])) {
                $cnt = Receiver::query()->where('name', trim($data['receiver']))
                    ->where('user_id', $this->user->id)->count();

                if ($cnt == 0) {
                    Receiver::create([
                        'user_id' => $this->user->id,
                        'name' => $data['receiver']
                    ]);
                }
            }

            \DB::commit();

            $files = $request->file('files');
            if (!empty($files) && is_array($files)) {
                foreach ($files as $key => $file) {
                    $name = time() . $file->getClientOriginalName();
                    $filePath = 'collect-spends/' . $collectSpend->id . '/files/' . str_slug($name);
                    $filePath = $filePath . '.' . $file->getClientOriginalExtension();
                    \Storage::disk('s3')->put($filePath, file_get_contents($file), 'public');
                    CollectSpendFile::create([
                        'collect_spend_id' => $collectSpend->id,
                        'name' => $file->getClientOriginalName(),
                        'file' => 'https://resident.sgp1.digitaloceanspaces.com/' . $filePath
                    ]);
                }
            }

            $deletedFiles = $request->input('deleted_files');
            if (is_array($deletedFiles) && !empty($deletedFiles)) {
                CollectSpendFile::query()->whereIn('id', $deletedFiles)->delete();
            }


            $user = Functions::getCurrentUser();
            $desc = '{'.$user->name.'} sửa phiếu thu {'.$collectSpend->name.'}';
            event(new LogAction([
                'type' => 'update-collect',
                'user_id' => optional($user)->id,
                'object_id' => $collectSpend->id,
                'hostel_id' => $collectSpend->hostel_id,
                'room_id' => $collectSpend->room_id,
                'properties' => $collectSpend->toArray(),
                'desc' => $desc
            ]));
        } catch (\Exception $exception) {
            \DB::rollBack();

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);
    }

    /**
     * @api {post} /create-type-collect Thêm loại phiếu thu
     * @apiName create-type-collect
     * @apiGroup Money
     * @apiParam {String} name Tên
     *
     * @apiDescription Api Thêm loại phiếu thu
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function storeSettingCollect(Request $request)
    {
        $data = $request->all();
        $ownerId = $this->user->id;
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }
        $data['owner_id'] = $ownerId;
        $item = TypeCollect::create($data);

        $user = Functions::getCurrentUser();
        $desc = '{' . optional($user)->name . '} thêm loại phiếu thu {' . $item->name . '}';
        event(new LogAction([
            'type' => 'create-type-collect',
            'user_id' => optional($user)->id,
            'object_id' => $item->id,
            'properties' => $item->toArray(),
            'desc' => $desc
        ]));

        return response([
            'status' => 1,
            'message' => 'Success',
            'data' => [
                'id' => $item->id,
                'name' => $item->name
            ]
        ]);

    }

    /**
     * @api {post} /create-type-spend Thêm loại phiếu chi
     * @apiName create-type-spend
     * @apiGroup Money
     * @apiParam {String} name Tên
     *
     * @apiDescription Api Thêm loại phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function storeSettingSpend(Request $request)
    {
        $data = $request->all();
        $ownerId = $this->user->id;
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }
        $data['owner_id'] = $ownerId;
        $item = TypeSpend::create($data);

        return response([
            'status' => 1,
            'message' => 'Success',
            'data' => [
                'id' => $item->id,
                'name' => $item->name
            ]
        ]);

    }

    /**
     * @api {post} /edit-type-spend Sua loại phiếu chi
     * @apiName edit-type-spend
     * @apiGroup Money
     * @apiParam {String} name Tên
     *   * @apiParam {String} id
     *
     * @apiDescription Api Thêm loại phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function editSettingSpend(Request $request)
    {
        $id = $request->input('id');
        $item = TypeSpend::find($id);
        if (!$item) {
            return response([
                'status' => 0
            ]);
        }
        $item->name = $request->input('name');
        $item->save();
        $user = Functions::getCurrentUser();
        $desc = '{' . optional($user)->name . '} sửa loại phiếu chi {' . $item->name . '}';
        event(new LogAction([
            'type' => 'update-type-spend',
            'user_id' => optional($user)->id,
            'object_id' => $item->id,
            'properties' => $item->toArray(),
            'desc' => $desc
        ]));

        return response([
            'status' => 1,
        ]);
    }

    /**
     * @api {post} /delete-type-spend Xoa loại phiếu chi
     * @apiName delete-type-spend
     * @apiGroup Money
     *   * @apiParam {String} id
     *
     * @apiDescription Api Thêm loại phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function deleteSettingSpend(Request $request)
    {
        $id = $request->input('id');
        $item = TypeSpend::find($id);
        if ($item) {
            $user = Functions::getCurrentUser();
            $desc = '{' . optional($user)->name . '} xóa loại phiếu chi {' . $item->name . '}';
            event(new LogAction([
                'type' => 'delete-type-spend',
                'user_id' => optional($user)->id,
                'object_id' => $item->id,
                'properties' => $item->toArray(),
                'desc' => $desc
            ]));
            $item->delete();
            return response([
                'status' => 1,
                'action' => 'Delete success!'
            ]);
        }

        return response([
            'status' => 0,
            'action' => 'Failed'
        ]);
    }

    /**
     * @api {post} /edit-type-collect Sua loại phiếu thu
     * @apiName edit-type-collect
     * @apiGroup Money
     * @apiParam {String} name Tên
     *   * @apiParam {String} id
     *
     * @apiDescription Api Thêm loại phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function editSettingCollect(Request $request)
    {
        $id = $request->input('id');
        $item = TypeCollect::find($id);
        if (!$item) {
            return response([
                'status' => 0
            ]);
        }
        $item->name = $request->input('name');
        $item->save();

        $user = Functions::getCurrentUser();
        $desc = '{' . optional($user)->name . '} sửa loại phiếu thu {' . $item->name . '}';
        event(new LogAction([
            'type' => 'update-type-collect',
            'user_id' => optional($user)->id,
            'object_id' => $item->id,
            'properties' => $item->toArray(),
            'desc' => $desc
        ]));

        return response([
            'status' => 1,
        ]);
    }

    /**
     * @api {post} /delete-type-collect Xoa loại phiếu thu
     * @apiName delete-type-collect
     * @apiGroup Money
     *   * @apiParam {String} id
     *
     * @apiDescription Api Thêm loại phiếu chi
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function deleteSettingCollect(Request $request)
    {
        $id = $request->id;
        $item = TypeCollect::find($id);
        if ($item) {
            if (!$item->can_delete) {
                return response([
                    'status' => 0,
                    'message' => 'Không thể xóa bản ghi này'
                ]);
            }
            $item->delete($id);

            $user = Functions::getCurrentUser();
            $desc = '{' . optional($user)->name . '} xóa loại phiếu thu {' . $item->name . '}';
            event(new LogAction([
                'type' => 'delete-type-collect',
                'user_id' => optional($user)->id,
                'object_id' => $item->id,
                'properties' => $item->toArray(),
                'desc' => $desc
            ]));
        }

        return response([
            'status' => 1,
            'action' => 'Success'
        ]);
    }

    /**
     * @api {get} /voucher-config Lay cai dat chan trang
     * @apiName voucher-config
     * @apiGroup Money
     *   * @apiParam {String} hostel_id
     *
     * @apiDescription Api Lay cai dat chan trang
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getVoucherConfig(Request $request)
    {
        $hostelId = $request->input('hostel_id');
        $ownerId = $this->user->id;
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }

        $text = null;
        $config = ConfigHostel::query()
            ->where('hostel_id', $hostelId)
            ->where('owner_id', $ownerId)
            ->first();
        if ($config) {
            $text = $config->voucher;
        }

        return response([
            'status' => 1,
            'data' => $text
        ]);
    }

    /**
     * @api {post} /voucher-config cai dat chan trang
     * @apiName create-voucher-config
     * @apiGroup Money
     *   * @apiParam {String} hostel_id
     *  * @apiParam {String} content
     *
     * @apiDescription Api cai dat chan trang
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function storeVoucherConfig(Request $request)
    {
        $hostelId = $request->input('hostel_id');
        $content = $request->input('content');
        $ownerId = $this->user->id;
        if ($this->user->type == User::STAFF) {
            $ownerId = $this->user->staff_owner_id;
        }

        ConfigHostel::query()
            ->updateOrCreate([
                'hostel_id' => $hostelId,
                'owner_id' => $ownerId
            ], [
                'hostel_id' => $hostelId,
                'owner_id' => $ownerId,
                'voucher' => $content
            ]);

        return response([
            'status' => 1,
        ]);
    }

}