<?php
/**
 *  予約
 *
 * @package     ci-hotel
 * @author      Teruki Hosokawa <hosotk@gmail.com>
 * @licence     New BSD Licence
 *
 */
require_once (dirname(__FILE__) . "/FRONT_Controller.php");

class Res extends FRONT_Controller {
    
    function Res()
    {
        parent::FRONT_Controller();
        $this->load->model('Common_model');
        $this->load->model('Res_model');
        $this->load->model('Hotel_model');
        $this->load->model('User_model');
    }
    
    /**
     * 条件入力
     * 
     * @param $d チェックイン日 YYYYMMDD
     */
    function index($hotelid, $planid, $d)
    {
        $error = array();
        $this->load->helper(array('form', 'url'));
        $this->load->library('form_validation');
        $this->form_validation->set_error_delimiters('<div class="error">', '</div>');
        $this->load->library('phpsession');
        
        $data['hotelid'] = $hotelid;
        $data['planid'] = $planid;
        $data['d'] = $d;
        $this->load->vars($data);
        
        $cin_y = substr($d, 0, 4);
        $cin_m = substr($d, 4, 2);
        $cin_d = substr($d, 6, 2);
        $cin = $cin_y . '-' . $cin_m . '-' . $cin_d;
        
        $this->db->select('guesttypes.guesttypeid, guesttypes.guesttype_name, rate');
        $this->db->from('guesttypes');
        $this->db->join('plan_to_guesttypes', 'plan_to_guesttypes.hotelid = guesttypes.hotelid AND plan_to_guesttypes.guesttypeid = guesttypes.guesttypeid');
        $this->db->where('plan_to_guesttypes.hotelid', $hotelid);
        $this->db->where('plan_to_guesttypes.planid', $planid);
        $query = $this->db->get();
        $guesttypes = $query->result_array();
        $data['guesttypes'] = $guesttypes;
        $this->load->vars($data);
        
        $this->form_validation->set_rules('stay_days', '宿泊日数', 'required|trim|xss_clean');
        $this->form_validation->set_rules('room_num', '部屋数', 'required|integer|trim|xss_clean');
        
        $this->db->where('hotelid', $hotelid);
        $this->db->where('planid', $planid);
        $this->db->where('status', 1);
        $query = $this->db->get('plans', 1);
        if ($query->num_rows() <= 0)
        {
            die('planid error!');
        }
        
        $row = $query->row_array();
        $data = $row;
        
        $max_days = $data['max_days'];
        $max_rooms = $data['max_rooms'];
        $this->load->vars($data);
        
        $roomtypeid = $row['roomtypeid'];
        $this->db->where('hotelid', $hotelid);
        $this->db->where('roomtypeid', $roomtypeid);
        $query = $this->db->get('roomtypes', 1);
        if ($query->num_rows() <= 0)
        {
            die('roomtyprid error!');
        }
        
        $row = $query->row_array();
        $data = $row;
        
        $data = array();
        $data['roomtype_name'] = $row['roomtype_name'];
        $data['roomtypes_guest_min'] = $row['guest_min'];
        $data['roomtypes_guest_max'] = $row['guest_max'];
        $this->load->vars($data);
        
        for ($i = 1; $i <= $max_rooms; $i++)
        {
            foreach ($guesttypes as $guesttype)
            {
                $guesttypeid = $guesttype['guesttypeid'];
                $form_guesttypes[$i][$guesttypeid] = $guesttype;
                $form_guesttypes[$i][$guesttypeid]['form_value'] = 0;
            }
        }
        $data = array();
        $data['form_guesttypes'] = $form_guesttypes;
        $this->load->vars($data);
        
        //--------------------------------------------------------------------
        // options
        $has_options = false;
        $form_options = array();
        for ($i = 0; $i < $max_days; $i++)
        {
            $baseSec = mktime(0, 0, 0, $cin_m, $cin_d, $cin_y);
            $addSec = $i * 86400;
            $targetSec = $baseSec + $addSec;
            $tmpDate = date("Y-m-d", $targetSec);
            
            /**
             * 1クエリで取りたいが方法がわからん...
             * とりあえずは、遅いだろうが2段階のクエリにする。
             */
            $this->db->select('optionid');
            $this->db->where('planid', $planid);
            $this->db->where('hotelid', $hotelid);
            $query = $this->db->get('plan_to_options');
            $options[$tmpDate] = array();
            foreach ($query->result_array() as $row)
            {
                $this->db->where('optionid', $row['optionid']);
                $this->db->where('hotelid', $hotelid);
                $this->db->where('status', 1);
                // $tmpDateが開始日～終了日であること
                // TODO
                $query2 = $this->db->get('options', 1);
                if ($query2->num_rows() > 0)
                {
                    $tmp = $query2->row_array();
                    $form_options[$tmpDate][$tmp['optionid']] = $tmp;
                    $has_options = true;
                }
            }
        }
        if ($has_options)
        {
            $data = array();
            $data['has_options'] = true;
            $data['form_options'] = $form_options;
            $this->load->vars($data);
        }
        //--------------------------------------------------------------------
        
        if (!$this->input->post('mysubmit'))
        {
            $data['stay_days'] = 1;
            $data['room_num'] = 1;
            $this->load->vars($data);
        }
        
        if ($this->form_validation->run() == FALSE)
        {
            $this->load->view('res/index');
        }
        else
        {
            $stay_days = set_value('stay_days');
            
            $baseSec = mktime(0, 0, 0, $cin_m, $cin_d, $cin_y);
            $addSec = $stay_days * 86400;
            $targetSec = $baseSec + $addSec;
            // チェックアウト日
            $cout = date("Y-m-d", $targetSec);
            
            $room_num = set_value('room_num');
            
            // 日付のチェック
            if ($this->Common_model->checkDate($cin) == false)
            {
                $data['error'] = array();
                $data['error'][] = 'チェックインの日付の形式が不正です。';
                $this->load->vars($data);
                $this->load->view('res/index');
                return;
            }
            
            // 休館日のチェック
            $this->db->where('day >=', $cin);
            $this->db->where('day <=', $cout);
            $this->db->where('hotelid', $hotelid);
            $this->db->where('daytypeid', 0);
            $query = $this->db->get('day_to_daytype', 1);
            if ($query->num_rows() > 0)
            {
                $data['error'] = array();
                $data['error'][] = '休館日が含まれています。';
                $this->load->vars($data);
                $this->load->view('res/index');
                return;
            }
            
            $this->db->where('hotelid', $hotelid);
            $this->db->where('planid', $planid);
            $query = $this->db->get('plan_prices');
            if ($query->num_rows() <= 0)
            {
                die('plan_prices error!');
            }
            foreach ($query->result() as $row)
            {
                $ppmat[$row->daytypeid][$row->guesttypeid] = $row->price;
            }
            //var_dump($ppmat);

            /**
             * プラン価格テーブルの作成
             * $ppmat[$daytype][$guesttype]
             * 
             */
            $this->db->select('daytypeid, daytype_name, rate');
            $this->db->from('daytypes');
            $this->db->where('hotelid', $hotelid);
            $this->db->where('status', 1);
            $this->db->order_by('ordering ASC');
            $query = $this->db->get();
            $daytypes = $query->result_array();
            
            //var_dump($daytypes);
            //var_dump($guesttypes);
            
            $basic_price = $ppmat[1][1];
            foreach ($daytypes as $daytype)
            {
                foreach ($guesttypes as $guesttype)
                {
                    if (isset($ppmat[$daytype['daytypeid']][$guesttype['guesttypeid']]))
                    {
                        //echo "ppmat[" . $daytype['daytypeid'] . "],[" . $guesttype['guesttypeid'] . "]<br />\n";
                    }
                    else
                    {
                        $ppmat[$daytype['daytypeid']][$guesttype['guesttypeid']]
                        = $basic_price * $daytype['rate'] * $guesttype['rate'] / 10000;
                    }
                }
            }
            //var_dump($ppmat);
            //die('break');
            
            /**
             * 以下の形式の配列を作成し、セッションに保存する。
             * reservation_detail[$date][$room_no][$guesttypeid] = array()
             */
             
            $tmp_y = substr($cin, 0, 4);
            $tmp_m = substr($cin, 5, 2);
            $tmp_d = substr($cin, 8, 2);
            $k = 0;
            $reservation_detail = array();
            
            $total_price = 0;
            for ($i = 0;; $i++)
            {
                $tmp_date = date('Y-m-d', mktime(0, 0, 0, $tmp_m, $tmp_d + $i, $tmp_y));
                if ($tmp_date >= $cout)
                {
                    break;
                }
                // 日程取得
                $dayType = 1;
                $this->db->where('day', $tmp_date);
                $this->db->where('hotelid', $hotelid);
                $query = $this->db->get('day_to_daytype', 1);
                if ($query->num_rows() > 0)
                {
                    $row = $query->row_array();
                    $dayType = $row['daytypeid'];
                }
                
                for ($j = 0; $j < $room_num; $j++)
                {
                    foreach ($guesttypes as $guesttype)
                    {
                        $guesttypeid = $guesttype['guesttypeid'];
                        $guesttype_name = $guesttype['guesttype_name'];
                        $num = $_POST['form_guesttypes'][$j + 1][$guesttypeid];
                        if ($num >= 1)
                        {
                            $subtotal = $num * $ppmat[$dayType][$guesttypeid];
                            $total_price += $subtotal;
                            
                            $reservation_detail[$tmp_date][$j + 1][$guesttypeid] = array(
                                'day' => $tmp_date,
                                'room_no' => $j + 1,
                                'daytypeid' => $dayType,
                                'guesttypeid' => $guesttypeid,
                                'guesttype_name' => $guesttype_name,
                                'num' => $num,
                                'price' => $ppmat[$dayType][$guesttypeid],
                                'subtotal' => $subtotal
                            );
                        }
                    }
                }
            }
            //var_dump($reservation_detail);
            $this->phpsession->save('reservation_detail', $reservation_detail);
            
            $option_total_price = 0;
            if (isset($_POST['form_options']))
            {
                //----------------------------------------------------------------
                // オプションをセッションに保存する。
                // reservation_options
                // reservation_options[$day][$optionid]
                //   = array(optionid, option_name, price, unitname, num, ...)
                $option_total_price = 0;
                $i = 0;
                $reservation_options = array();
                foreach ($_POST['form_options'] as $key => $value)
                {
                    $tmp_resoptions_date = array();
                    foreach ($value as $key2 => $value2)
                    {
                        // $key2 -> optionid
                        $tmp = array(
                            'optionid' => $key2,
                            'option_name' => $form_options[$key][$key2]['option_name'],
                            'price' => $form_options[$key][$key2]['price'],
                            'unitname' => $form_options[$key][$key2]['unitname'],
                            'num' => $value2);
                        if ($tmp['num'] > 0)
                        {
                            $tmp_resoptions_date[$key2] = $tmp;
                            $option_subtotal = $tmp['price'] * $tmp['num'];
                            $option_total_price += $option_subtotal;
                        }
                    }
                    if (count($tmp_resoptions_date) > 0)
                    {
                        $reservation_options[$key] = array();
                        $reservation_options[$key] = $tmp_resoptions_date;
                    }
                    
                    $i++;
                    if ($i >= set_value('stay_days'))
                    {
                        break;
                    }
                }
                $this->phpsession->save('reservation_options', $reservation_options);
                //----------------------------------------------------------------
            }
            
            // 入力値をセッションに保存する。
            $this->phpsession->save('reservation',
                array('cin' => $cin,
                      'cout' => $cout,
                      'stay_days' => set_value('stay_days'),
                      'hotelid' => $hotelid,
                      'planid' => $planid,
                      'roomtypeid' => $roomtypeid,
                      'room_num' => $room_num,
                      'total_price' => ($total_price + $option_total_price)));
            
            /**
             * 空きのチェックを行う。
             */
            $ret = $this->Res_model->doRes(Res_model::RESMODE_CHECK, null);
            if ($ret >= 0)
            {
                redirect('res/estimate/' . $hotelid);
            }
            else
            {
                $s = $this->Res_model->getErrorString($ret);
                $data['error'] = array();
                $data['error'][] = $s;
                $this->load->vars($data);
                $this->load->view('res/index');
            }
        }
    }
    
    /**
     * 見積もり,ユーザ情報入力方法の選択
     * - ログインする
     * - 未登録で予約する
     * - ユーザ登録する
     */
    function estimate($hotelid)
    {
        $this->load->library('phpsession');
        $this->load->helper(array('MY_form', 'MY_url'));
        
        $reservation = $this->phpsession->get('reservation');
        $planid = $reservation['planid'];
        $this->db->where('hotelid', $hotelid);
        $this->db->where('planid', $planid);
        $query = $this->db->get('plans', 1);
        if ($query->num_rows() < 0)
        {
            die('planid error!');
        }
        $row = $query->row_array();
        $data = $row;
        
        $data['hotelid'] = $hotelid;
        $data['planid'] = $planid;
        $this->load->vars($data);
        
        $roomtypeid = $row['roomtypeid'];
        $this->db->where('hotelid', $hotelid);
        $this->db->where('roomtypeid', $roomtypeid);
        $query = $this->db->get('roomtypes', 1);
        if ($query->num_rows() < 0)
        {
            die('roomtypeid error!');
        }
        $row = $query->row_array();
        $data = $row;
        
        $data['roomtype_name'] = $row['roomtype_name'];
        $data['roomtypes_guest_min'] = $row['guest_min'];
        $data['roomtypes_guest_max'] = $row['guest_max'];
        $this->load->vars($data);
        
        // ログインしているか？
        if ($this->User_model->isMember() == true)
        {
            $data['isloggedin'] = true;
        }
        else
        {
            $data['isloggedin'] = false;
        }
        $this->load->vars($data);
        
        // 見積画面を表示する
        $this->load->view('res/estimate');
    }
    
    /**
     * ログイン (予約手続き中でのログイン)
     */
    function login($hotelid)
    {
        $this->load->library('phpsession');
        $this->load->helper(array('MY_form', 'MY_url'));
        $this->load->library('form_validation');
        
        $this->form_validation->set_rules('email', 'メールアドレス', 'required|valid_email|trim|xss_clean');
        $this->form_validation->set_rules('password', 'パスワード', 'required|trim|xss_clean');
        
        if ($this->form_validation->run() == FALSE)
        {
            $this->load->view('res/login');
            return;
        }
        else
        {
            $email = set_value('email');
            $password = set_value('password');
            
            // email, passwordをチェックする
            $this->db->where('email', $email);
            $this->db->where('password', sha1($password));
            $this->db->where('status', 1);
            $query = $this->db->get('members', 1);
            if ($query->num_rows() > 0)
            {
                $row = $query->row_array();
                $this->phpsession->save('member',
                    array('memberid' => $row['memberid'],
                          'name' => $row['name'],
                          'hotelid' => $row['hotelid'],
                          'email' => $row['email']));
                // 最終ログイン日時を更新する
                $data = array('last_login' => date("Y-m-d H:i:s"));
                $this->db->where('memberid', $row['memberid']);
                $this->db->update('members', $data);
                redirect('res/userinp/' . $hotelid);
            }
            else
            {
                $data['error'] = "メールアドレス、またはパスワードが間違っています。";
                $this->load->vars($data);
                $this->load->view('res/login');
                return;
            }
        }
    }
    
    /**
     * ユーザ情報の入力
     */
    function userinp($hotelid)
    {
        $this->load->helper(array('MY_form', 'MY_url'));
        $this->load->library('phpsession');
        
        $data['hotelid'] = $hotelid;
        $this->load->vars($data);
        
        $this->load->library('form_validation');
        $this->form_validation->set_error_delimiters('<div class="error">', '</div>');
        
        $this->form_validation->set_rules('name', '氏名', 'required|trim|xss_clean');
        $this->form_validation->set_rules('name_kana', '氏名(かな)', 'required|trim|xss_clean|callback_hiragana_check');
        $this->form_validation->set_rules('email', 'メールアドレス', 'required|valid_email|trim|xss_clean');
        $this->form_validation->set_rules('postcode', '郵便番号', 'required|trim|xss_clean|callback_postcode_check');
        $this->form_validation->set_rules('prefecture', '都道府県', 'required|trim|xss_clean');
        $this->form_validation->set_rules('city', '市区町村', 'required|trim|xss_clean');
        $this->form_validation->set_rules('street', '番地', 'required|trim|xss_clean');
        $this->form_validation->set_rules('phone', '電話番号', 'required|trim|xss_clean|callback_phone_check');
        $this->form_validation->set_rules('cinhour', 'チェックイン時刻', 'trim|xss_clean');
        $this->form_validation->set_rules('memo', '備考', 'xss_clean');

        // フォームの初期値設定
        // ログインしているときは、ユーザ情報を初期値に設定する。
        if (!$this->input->post('submit'))
        {
            $member = $this->phpsession->get('member');
            if (!is_null($member))
            {
                $this->db->where('memberid', $member['memberid']);
                $query = $this->db->get('members', 1);
                if ($query->num_rows() > 0)
                {
                    $row = $query->row_array();
                    $data['name'] = $row['name'];
                    $data['name_kana'] = $row['name_kana'];
                    $data['email'] = $row['email'];
                    $data['postcode'] = $row['postcode'];
                    $data['prefecture'] = $row['prefecture'];
                    $data['city'] = $row['city'];
                    $data['street'] = $row['street'];
                    $data['phone'] = $row['phone'];
                    $this->load->vars($data);
                }
            }
        }
        
        if ($this->form_validation->run() == FALSE)
        {
            $this->load->view('res/userinp');
        }
        else
        {
            // ユーザ情報をセッションに保存する
            $this->phpsession->save('reservation_member',
                array(
                    'name' => set_value('name'),
                    'name_kana' => set_value('name_kana'),
                    'email' => set_value('email'),
                    'postcode' => set_value('postcode'),
                    'prefecture' => set_value('prefecture'),
                    'city' => set_value('city'),
                    'street' => set_value('street'),
                    'phone' => set_value('phone'),
                    'cinhour' => set_value('cinhour'),
                    'memo' => set_value('memo')));
            redirect('res/confirm/' . $hotelid);
        }
    }
    
    /**
     * 確認
     */
    function confirm($hotelid)
    {
        $this->load->helper(array('form', 'url'));
        $this->load->library('phpsession');
        
        $this->Hotel_model->load($hotelid);
        
        $reservation = $this->phpsession->get('reservation');
        $planid = $reservation['planid'];
        $this->db->where('planid', $planid);
        $query = $this->db->get('plans', 1);
        if ($query->num_rows() > 0)
        {
            $row = $query->row_array();
            $data = $row;
        }
        $data['hotelid'] = $hotelid;
        $data['planid'] = $planid;
        $this->load->vars($data);
        
        $roomtypeid = $row['roomtypeid'];
        $this->db->where('roomtypeid', $roomtypeid);
        $query = $this->db->get('roomtypes', 1);
        if ($query->num_rows() > 0)
        {
            $row = $query->row_array();
            $data = $row;
        }
        $data['roomtype_name'] = $row['roomtype_name'];
        $data['roomtypes_guest_min'] = $row['guest_min'];
        $data['roomtypes_guest_max'] = $row['guest_max'];
        $this->load->vars($data);
        
        if ($this->input->post('submit'))
        {
            // 
            log_message('info', 'Res_model->doRes() >>');
            
            if ($this->Hotel_model->res_mode == 1)
            {
                $resid = $this->Res_model->doRes(Res_model::RESMODE_TENTATIVE, $this->Hotel_model);
            }
            else
            {
                $resid = $this->Res_model->doRes(Res_model::RESMODE_REGULAR, $this->Hotel_model);
            }
            if ($resid < 0)
            {
                log_message('info', 'Res_model->doRes() NG <<');
                // 予約失敗
                redirect('res/failure/' . $hotelid . '/' . $resid);
            }
            log_message('info', 'Res_model->doRes() OK <<');
            
            redirect('res/accept/' . $hotelid);
        }
        
        $this->load->view('res/confirm');
    }
    
    /**
     * 予約完了画面
     */
    function accept($hotelid)
    {
        $this->load->helper(array('form', 'url'));
        $this->load->library('phpsession');
        
        $data['hotelid'] = $hotelid;
        $data['resid'] = $this->phpsession->get('resid');
        $data['rescode'] = $this->phpsession->get('rescode');
        
        $this->load->vars($data);
        
        $this->load->view('res/accept');
    }
    
    /**
     * 予約失敗画面
     * # 予約処理中に他の予約が完了したときに発生する。
     */
    function failure($hotelid, $errorcode)
    {
        $this->load->helper(array('form', 'url'));
        $this->load->library('phpsession');
        
        switch ($errorcode)
        {
        }
        
        $this->load->view('res/failure');
    }
    
    /**
     * ひらがな文字列のチェック
     */
    function hiragana_check($str)
    {
        mb_regex_encoding("UTF-8");
        $regex = "^[ぁ-ん]+$";
        if (mb_ereg($regex, $str))
        {
            return true;
        }
        $this->form_validation->set_message('hiragana_check', 'フィールド %s に、ひらがな以外の文字は使えません');
        return false;
    }
    
    /**
     * 電話番号チェック
     */
    function phone_check($str)
    {
        mb_regex_encoding("UTF-8");
        $regex = '/^\d{1,5}-?\d{1,5}-?\d{1,5}$/';
        $regex2 = '/^\d{10,11}$/';
        if (preg_match($regex, $str, $matches) || preg_match($regex2, $str, $matches))
        {
            return true;
        }
        else 
        {
            $this->form_validation->set_message('phone_check', 'フィールド %s が、電話番号の形式になっていません');
            return false;
        }
    }
    
    /**
     * 郵便番号チェック
     */
    function postcode_check($str)
    {
        mb_regex_encoding("UTF-8");
        $regex = '/^\d{3}-?\d{4}$/';
        $regex2 = '/^\d{7}$/';
        if (preg_match($regex, $str, $matches) || preg_match($regex2, $str, $matches))
        {
            return true;
        }
        else
        {
            $this->form_validation->set_message('postcode_check', 'フィールド %s が、郵便番号の形式になっていません');
            return false;
        }
    }
}

/* End of file res.php */
