【Laravel】スケジュールの重複をチェックする

前回までの状況はこちら。

最新ソースはこちら。

https://github.com/takishita2nd/hotel-mng

今回も内容薄いかもしれん。

今までは予約登録時、日にちが重複していればエラーを表示させていました。

これが通用するのは部屋が一つしか無い場合のみでして、

今回は部屋が複数あるので、日にちだけのチェックだけではなくて、部屋もチェックに含めなければいけません。

というわけで、引数に部屋IDを追加。

    /**
     * 登録処理
     */
    public function store(ManagementRequest $request)
    {
        if($this->registerManagement->checkSchedule($request->start_day, 
                                                    $request->days, 
                                                    $request->room) == false)
        {
            return redirect('management/create')
                        ->with(['error' => 'スケジュールが重複します'])
                        ->withInput();
        }
    /**
     * 更新処理
     */
    public function update(ManagementRequest $request)
    {
        if($this->registerManagement->checkScheduleForUpdate($request->start_day, 
                                                            $request->days, 
                                                            $request->id, 
                                                            $request->room) == false)
        {
            return redirect('management/create')
                        ->with(['error' => 'スケジュールが重複します'])
                        ->withInput();
        }

そしてチェック処理本体。

    /**
     * スケジュールの重複を確認する
     * 
     * @return boolean
     */
    public function checkSchedule($date, $num, $room)
    {
        for($i = 0; $i < $num; $i++)
        {
            $record = ReserveDayList::where(['day' => date('Y-m-d', strtotime($date.'+'.$i.' day'))])->first();
            if(is_null($record) == false)
            {
                if($record->reserveManagements()->first()->rooms()->first()->id == $room)
                {
                    return false;
                }
            }
        }

        return true;
    }
    /**
     * 更新時のスケジュールの重複を確認する
     * 
     * @return boolean
     */
    public function checkScheduleForUpdate($date, $num, $userId, $room)
    {
        for($i = 0; $i < $num; $i++)
        {
            $model2 = ReserveDayList::where(['day' => date('Y-m-d', strtotime($date.'+'.$i.' day'))])->first();
            if(is_null($model2) == false)
            {
                if($model2->reserveManagements()->first()->rooms()->first()->id == $room)
                {
                    if($model2->reserveManagements()->first()->id != $userId)
                    {
                        return false;
                    }
                }
            }
        }

        return true;
    }

strtotime($date.’+0 day’)ってできたんだ。

やってることは部屋チェックを追加しただけです。

簡単ですね。

これで、日付は同じだけど部屋が違う場合は予約可、日付と部屋が同じ場合は予約不可、というロジックが完成しました。

バナークリックで応援よろしくおねがいします。

【バンドリ】【ガルパ】BanG Dream! 3rd SEASON発表会での新情報

本日行われたBanG Dream! 3rd season発表会の内容からバンドリ!ガールズバンドパーティ!の情報を抜粋します。

新曲追加

BanG Dream! 3rd seasonのOP「イニシャル」が本日21時に追加されました。

他2曲も実装予定です。

カバー曲キャンペーン。

Twitter上での予想は、

マクロス・Fの「ライオン」?

五等分の花嫁の「五等分の気持ち」?

「!」はいろいろ予想が別れているようです。

というか、これだけじゃわからんわ。

12月22日のハロハピ放送局で明らかになるようです。

その他、ログインキャンペーンなどが行われます。

年末年始も眠れない。

【自作PC】【男のロマン】フルスペックのMac Proに対抗できる自作PCを考えてみる

実際に組むわけではないけど、もしMac Proに対抗できる自作PCを作ったら、という前提で検討してみた。

もはやこれは男のロマンの話です。

オイラが机上で考えた構成なので、動作確認はできません。

自己責任でお願いします。

買えるとは思えませんが。

CPU

Xeon W-3275M

https://kakaku.com/item/K0001211650/

型番の後ろにMが付いているのと付いていないのがありますが、Mが無いと、メモリ1TBまでしか認識しないそうです。

つまり、Mac Proのフルスペックが1.5TBなので、必然的にMが付いたモデルになります。

97万円。

マザーボード

Z11PA-U12

https://kakaku.com/item/K0001043740/

Mac Proのフルスペックである1.5TBのメモリを搭載するにはメモリスロット12個のマザーボードに128GBのメモリを搭載しなければいけません。

その上で、CPUに対応するソケットはLGA3647なので、それに対応するマザーボードを選択しました。

6万円。

でもさらに上を行くこともできます。

CPU2個搭載するモデルですが、メモリスロット16個のヤツを買えばメモリ2TBが可能です。

メモリ

クルーシャル 128GB DDR4 2666 MT/s (PC4-21300) CL19 Octal-Rank x4 CT128G4ZFJ426S

https://www.askul.co.jp/p/E693297/?int_id=recom_DtVar

上にも書いたとおり、1.5TBのメモリを実現するには、128GBのメモリが12枚必要です。

22万円×12枚=264万円。

グラフィックボード

HP Q1K37A AMD Radeon Pro WX7100 GPU モジュール

https://product.rakuten.co.jp/product/-/cea5a95901c6a369598272b7921f253a/?scid=we_twt_upc249

最近出たばかりのグラボですが、これがMac Proと同じモデルのはずです。

16万円。

ストレージ

7.68TB 5210 ION SSD SATA 2.5インチ エンタープライズ

この当たりだったら購入しても現実的に使えそう。

8TBのSSDです。

13万円。

あとは、電源ユニット、PCケース、CPUクーラーなどがありますが、価格.comでも多くの種類がヒットしますし、そんなに値段もしないでしょう。

とりあえず、一番お金がかかりそうなところをピックアップしてみました。

総額。

およそ400万円。(+電源とかいろいろ)

すごいぞ、自作PcならMac Proに匹敵するPCを400万で作れる!(机の上の計算では)

バナークリックで応援よろしくおねがいします。

【Laravel】【ホテル予約管理】スケジュールと部屋の連携

前回までの状況はこちら

最新ソースはこちら

https://github.com/takishita2nd/hotel-mng

今回は中身薄いかも。

スケジュール画面に部屋名を表示させます。

難しいことはなく、画面に部屋名の表示を付け足すだけです。

                    <table class="schedule">
                        <tr>
                            <th class="date">日時</th>
                            <th class="name">名前</th>
                            <th class="room">部屋</th>
                            <th class="lodging">宿泊状況</th>
                        </tr>
                    @foreach ($Lists as $list)
                        <tr>
                            <td class="date">{{ $list['day'] }}</td>
                            <td class="name">{{ $list['name'] }}</td>
                            <td class="room">{{ $list['room'] }}</td>
                            @if ($list['lodging'])
                                <td class="lodging">チェック</td>
                            @else
                                <td class="lodging">未チェック</td>
                            @endif
                        </tr>
                    @endforeach
                    </table>
    /**
     * スケジュール一覧を取得する
     */
    public function getSchedule()
    {
        $lists = array();
        $index = 0;
        $models = ReserveDayList::orderBy('day')
                                    ->get();
        foreach($models as $model)
        {
            $lists[$index] = array(
                                'day' => $model->day,
                                'name' => $model->reserveManagements()->first()->name,
                                'room' => $model->reserveManagements()->first()->rooms()->first()->name,
                                'lodging' => $model->reserveManagements()->first()->lodging
                            );
            $index++;
        }
        return $lists;
    }

    /**
     * 月別スケジュール一覧を取得する
     */
    public function getScheduleByMonth($year, $month)
    {
        $lists = array();
        $index = 0;
        $models = ReserveDayList::where('day', '>=', date('Y-m-d', strtotime('first day of '.$year.'-'.$month)))
                                ->where('day', '<=', date('Y-m-d', strtotime('last day of '.$year.'-'.$month)))
                                ->orderBy('day')
                                ->get();
        foreach($models as $model)
        {
            $lists[$index] = array(
                                'day' => $model->day,
                                'name' => $model->reserveManagements()->first()->name,
                                'room' => $model->reserveManagements()->rooms()->first()->name,
                                'lodging' => $model->reserveManagements()->first()->lodging
                                );
            $index++;
        }
        return $lists;
    }

レコード一件ずつ参照してデータを取り出しているので、同じようにリレーションを使って部屋テーブルの部屋名を取り出している、という感じですね。

今回は難しくなかった。

残るは、部屋の競合チェック処理を変えなくちゃいけないのと、部屋でフィルタ表示させたい。

あとは部屋ごとの集計かな。

バナークリックで応援よろしくお願いします。

【Laravel】【ホテル予約管理】予約一覧に部屋を連携させる

前回までの様子はこちら

最新ソースはこちら

https://github.com/takishita2nd/hotel-mng

前回は部屋を登録・編集・削除できるようにしましたので、これを予約管理と連携させます。

まずは一覧表示。

リポジトリのget処理を修正します。

    /**
     * 予約一覧を取得する
     * 
     * @return ReserveManagement[]
     */
    public function getList()
    {
        $select = ['reserve_managements.id as id', 'reserve_managements.name as name', 'address', 'phone', 'num', 'rooms.name as room', 'days', 'start_day'];
        return ReserveManagement::select($select)
                                    ->where('lodging', false)
                                    ->orderBy('start_day')
                                    ->leftJoin('reserve_management_room', 'reserve_managements.id', '=', 'reserve_management_room.reserve_management_id')
                                    ->leftJoin('rooms', 'reserve_management_room.room_id', '=', 'rooms.id')
                                    ->get();
    }

結合を使って一覧画面に部屋名も出力されます。

おそらくリレーションを使うよりはこちらのほうが早いような気がします。

次は予約登録処理。

登録画面には、部屋テーブルの中身をコンボボックスで選択できるようにします。

                    <tr>
                        <th>宿泊部屋</th>
                        <td>{!! Form::select('room', $rooms) !!}</td>
                    </tr>
    /**
     * 入力フォーム
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('register.create',
                    ['rooms' => $this->roomRepository->getRoomList()]);
    }
    /**
     * IDと部屋名のリストを取得する
     */
    public function getRoomList()
    {
        $rooms = Array();
        foreach(Room::get() as $room)
        {
            $rooms[$room->id] = $room->name;
        }
        return $rooms;
    }

実際に登録を行う際は、POSTリクエストの部屋IDを受け取ることになります。

予約レコードと部屋レコードを中間テーブルで連携させることで予約と部屋を紐づけします。

    /**
     * 登録処理
     */
    public function store(ManagementRequest $request)
    {
        if($this->registerManagement->checkSchedule($request->start_day, $request->days) == false)
        {
            return redirect('management/create')
                        ->with(['error' => 'スケジュールが重複します'])
                        ->withInput();
        }
        $param = $this->registerManagement->getParam();
        $this->registerManagement->add([
            $param[0] => $request->name,
            $param[1] => $request->address,
            $param[2] => $request->phone,
            $param[3] => $request->num,
            $param[4] => $request->days,
            $param[5] => $request->start_day,
            $param[6] => false
        ], $request->room);
        return redirect('management');
    }
    /**
     * 予約を登録する
     * 
     * @return void
     */
    public function add($param, $room)
    {
        $model = new ReserveManagement;
        foreach($this->paramNames as $name)
        {
            $model->$name = $param[$name];
        }
        $model->save();
        $this->attachToRoom($model, $room);
        $this->attachToSchedule($model);
    }
    public function attachToRoom($model, $room)
    {
        $model3 = Room::where('id', $room)->first();
        $model->rooms()->attach($model3);
    }

予約編集も同様。

                    <tr>
                        <th>宿泊部屋</th>
                        <td>{!! Form::select('room', $rooms, $item->room_num) !!}</td>
                    </tr>
    /**
     * 編集処理
     *
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        return view('register.edit',
                    ['item' => $this->registerManagement->getReserveById($id),
                     'rooms' => $this->roomRepository->getRoomList()]);
    }
    /**
     * 予約を一件取得する
     */
    public function getReserveById($id)
    {
        $model = $this->getItemById($id);
        $model->room_num = $model->rooms()->first()->id;
        $model->room_name = $model->rooms()->first()->name;
        return $model;
    }

一件のデータの場合はリレーションを使うのが簡単です。これができるLaravelはホント便利。

    /**
     * 更新処理
     */
    public function update(ManagementRequest $request)
    {
        if($this->registerManagement->checkScheduleForUpdate($request->start_day, $request->days, $request->id) == false)
        {
            return redirect('management/create')
                        ->with(['error' => 'スケジュールが重複します'])
                        ->withInput();
        }
        $param = $this->registerManagement->getParam();
        $this->registerManagement->updateById($request->id,
        [
            $param[0] => $request->name,
            $param[1] => $request->address,
            $param[2] => $request->phone,
            $param[3] => $request->num,
            $param[4] => $request->days,
            $param[5] => $request->start_day,
            $param[6] => false
        ], $request->room);
        return redirect('management');
    }
    /**
     * 予約を更新する
     * 
     * @return void
     */
    public function updateById($id, $param, $room)
    {
        $model = $this->getItemById($id);
        foreach($this->paramNames as $name)
        {
            $model->$name = $param[$name];
        }
        $model->save();
        $this->detachToRoom($model, $model->rooms()->first()->id);
        $this->detachToSchedule($model);
        $this->attachToRoom($model, $room);
        $this->attachToSchedule($model);
    }
    public function detachToRoom($model, $room)
    {
        $model3 = Room::where('id', $room)->first();
        $model->rooms()->detach($model3);
    }

一旦古い情報でデタッチし、新しい情報でアタッチします。

削除も同じように、

                    <tr>
                        <th>宿泊部屋</th>
                        <td>{!! $item->room_name !!}</td>
                    </tr>
    /**
     * 削除確認
     *
     * @return \Illuminate\Http\Response
     */
    public function conform($id)
    {
        return view('register.conform', ['item' => $this->registerManagement->getReserveById($id)]);
    }
    /**
     * 予約を削除する
     * 
     * @return void
     */
    public function deleteById($id)
    {
        $model = $this->getItemById($id);
        $this->detachToRoom($model, $model->rooms()->first()->id);
        $this->detachToSchedule($model);
        $model->delete();
    }

そんなにソースコードは変更していないけど、一気に進みましたね。

次回はスケジュールを部屋ごとに表示するところをやっていきます。

バナークリックで応援よろしくお願いします。

【SocialDog】みなさん、ツイッターの管理ってどうしていますか?

自分のTwitterアカウントもフォロワー数2300とありがたい数字になっているのですが、

いま、問題が発生しておりまして、

もっとフォロワーを増やしたいのですが、これ以上フォローできない、という事態に陥ってまして、

というのも、ツイッターの制限で、フォロワー数が一定以上いかないと、フォロー数が5000で制限されてしまうのです。

これを解決するためには、昔フォローしたけど見る価値のないアカウントのフォロー解除を行わなければなりません。

ここでいう、見る価値のないアカウントというのは、しばらくツイートしていない、いわゆる休眠アカウントと呼ばれるアカウントです。

でも、それを区別するのは、いつものツイッタークライアントでは非常に難しい。

というわけで、ツイッター管理ツールというのが必要になるわけです。

オイラが検索して見つけたのは、SocialDogというツイッター管理ツール。

本来、企業のツイッターアカウントを管理するためのツールなのですが、一般ユーザーでも機能制限付きで無料で使用できます。

便利なのがフォロー管理という機能で、この画面で、相互フォローしているアカウント、フォローしているけどフォローバックされていないアカウント(片思いアカウント)、フォローしていないフォロワー(ファンアカウント)がリスト化して表示されているのです。

便利なのが、休眠アカウントをリスト表示してくれる機能。

もちろんこの画面からフォロー解除することもできます。

こういったツールってホント便利ですよね。

Twitterアカウントがあれば簡単にアカウント登録できるのも嬉しいですよね。

こういう情報、もっとたくさんの人に伝われ。

バナークリックで応援よろしくお願いします。

シャオミ、日本上陸

こちらの記事でも書きましたが、

大方、予想通りでした。

Mi Note 10とMi Note 10 Proを日本市場に投入です。

購入はAmazonで購入できます。

通常とProの違いは主にメモリの容量とストレージの容量ですね。

ミドルレンジでこの価格でこの容量はかなりお得感があります。

ちなみに残念ながらFelica(おサイフケータイ)には対応していないようです。

バナークリックで応援よろしくお願いします。

【Laravel】【ホテル予約管理】部屋を増設する

次の課題は「部屋を増設し、部屋別に管理を行う」というものでした。

今までは部屋は一つの前提で作ってきたので、これを改造する必要があります。

たぶん、テーブルはこんな感じで大丈夫だと思う。

どうせ集計時に全部結合されるんだから。

データベースの作成。マイグレーションを追加します。

class CreateRoomTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('rooms', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->integer('price');
            $table->timestamps();
            $table->engine = 'InnoDB';
            $table->charset = 'utf8mb4';
            $table->collation = 'utf8mb4_unicode_ci';
        });
        Schema::create('reserve_management_room', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('reserve_management_id')
                  ->foreign('reserve_management_id')
                  ->references('id')->on('reserve_managements')
                  ->onDelete('cascade');
            $table->integer('room_id')
                  ->foreign('room_id')
                  ->references('id')->on('rooms')
                  ->onDelete('cascade');
            $table->timestamps();
            $table->engine = 'InnoDB';
            $table->charset = 'utf8mb4';
            $table->collation = 'utf8mb4_unicode_ci';
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('reserve_management_room');
        Schema::dropIfExists('rooms');
    }
}

このテーブルに対するCURD機能を作成します。

ここらへんは予約一覧がすでに出来上がっているので、これをベースにすれば簡単に出来上がります。

モデル

class Room extends Model
{
    protected $table = 'rooms';

    public function reserveManagement()
    {
        return $this->belongsToMany('App\Model\ReserveManagement');
    }
}

リポジトリ

class RoomRepository
{
    private $paramNames = ['name', 'price'];

    /**
     * 部屋一覧を取得する
     * 
     * @return Room[]
     */
    public function getList()
    {
        return Room::get();
    }

    /**
     * 部屋を登録する
     * 
     * @return void
     */
    public function add($param)
    {
        $model = new Room;
        foreach($this->paramNames as $name)
        {
            $model->$name = $param[$name];
        }
        $model->save();
    }

    /**
     * 予約を更新する
     * 
     * @return void
     */
    public function updateById($id, $param)
    {
        $model = $this->getItemById($id);
        foreach($this->paramNames as $name)
        {
            $model->$name = $param[$name];
        }
        $model->save();
    }

    /**
     * 予約を削除する
     * 
     * @return void
     */
    public function deleteById($id)
    {
        $model = $this->getItemById($id);
        $model->delete();
    }

    /**
     * IDから部屋情報を1件取得する
     * 
     * @return Room
     */
    public function getItemById($id)
    {
        return Room::where(['id' => $id])->first();
    }

    public function getParam()
    {
        return $this->paramNames;
    }

}

リクエスト

class RoomRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|string',
            'price' => 'required|numeric',
        ];
    }
}

コントローラー

class RoomController extends Controller
{
    protected $room;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        $this->room = new RoomRepository();
    }

    /**
     * 部屋一覧の表示
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('room.index', ['roomLists' => $this->room->getList()]);
    }

    /**
     * 入力フォーム
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('room.create');
    }

    /**
     * 登録処理
     */
    public function store(RoomRequest $request)
    {
        $param = $this->room->getParam();
        $this->room->add([
            $param[0] => $request->name,
            $param[1] => $request->price,
        ]);
        return redirect('room');
    }

    /**
     * 編集処理
     *
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        return view('room.edit', ['item' => $this->room->getItemById($id)]);
    }

    /**
     * 更新処理
     */
    public function update(RoomRequest $request)
    {
        $param = $this->room->getParam();
        $this->room->updateById($request->id,
        [
            $param[0] => $request->name,
            $param[1] => $request->price,
        ]);
        return redirect('room');
    }

    /**
     * 削除確認
     *
     * @return \Illuminate\Http\Response
     */
    public function conform($id)
    {
        return view('room.conform', ['item' => $this->room->getItemById($id)]);
    }

    /**
     * 削除処理
     */
    public function delete(Request $request)
    {
        $this->room->deleteById($request->id);
        return redirect('room');
    }

}

ルーティング

Route::get('/room', 'RoomController@index');
Route::get('/room/create', 'RoomController@create');
Route::post('/room', 'RoomController@store');
Route::get('/room/{id}/edit', 'RoomController@edit');
Route::post('/room/update', 'RoomController@update');
Route::get('/room/{id}/conform', 'RoomController@conform');
Route::post('/room/delete', 'RoomController@delete');

とりあえずこれでOKかと。

次回は予約登録時に部屋を指定する仕組みを作成します。

バナークリックで応援よろしくお願いします。

【ぼっち】北海堂

昨日病院帰りにサクッと飲んできました。

ラフィラの地下にある食堂っぽいお店。

午前10時からオープンしていて、ビール中ジョッキが250円で飲むことができます。

もちろんランチも食べられます。

鮭とばキムチ。

オススメのポテトサラダ。

1時間でサクッと飲むには十分でした。

バナークリックで応援よろしくお願いします。

【自作PC】グラボが届きました。

ついに届きました。

待ちに待ったグラフィックボード、SAPPHIRE PULSE RADEON RX 570 8G GDDR5!

特に必須というわけではないのですが、

なぜなら、今使用しているRyzen 5 3400Gはグラフィックスチップを搭載しています。

インテル系のCPUを使用している場合はグラボが無くても、内蔵のグラフィックスチップで画面表示できますが、AMDのCPUは基本グラフィックスチップを搭載していないので、グラボは必須になります。

グラボを購入した目的は、今後CPUをパワーアップをするに当たり、グラフィックスチップが搭載されていないCPUかもしれないというのもあって、グラボの購入を決定しました。

まぁ、今後PCをさらにパワーアップさせるための足がかりです。

また、このパーツを選んだ理由は、

今使用しているグラフィックスのメモリは2GBなのに対して、今回選択した物は8GB。

そのスペックに対して14000円台とグラボにしてはお手軽価格で、価格.comでも評価は高いです。

それでは開封。

ファン付きのグラボって本格っぽいよね。

HDMTが二つと、DPが二つ使えます。

ここにグラボ用の電源を繋げます。

ローエンドのグラボではマザーからの電力で十分ですが、ミドルエンド以上になると、別途電源ユニットから電源を貰わないと動かすことができません。

それだけ電気を使うのですね。

当然、消費電力をまかなえるように電源ユニットを用意しなければなりません。

取り付けました。

ネジが合っているかどうかわかりません。

しかし、電源を入れたときに、グラボのファンがグラボの下のケーブルに干渉して、ガガガガと音がしていたので、

干渉しないように結束バンドでまとめました。

今のところ、問題無いように動いています。

グラボを増設したらどれだけスペックアップしたか見てみたいでしょ。

ということで、ベンチマークソフトを動かしました。

使用するソフトと条件は、前回こちらで実施したものと同じです。

やはり全体的にスコアが上がっています。

特にFF14が「やや快適」から「非常に快適」になり、

FF15が「動作困難」から「やや快適」になりました。

やったぁ。

これで、いつでも第3世代Ryzenを迎えられる準備ができました。

バナークリックで応援よろしくお願いします。

自分、ぼっちですが何か?