本日の成果。
特にプログラム組まなくてもここまでできました。
本日の成果。
特にプログラム組まなくてもここまでできました。
前回までの状況はこちら。
最新ソースはこちら。
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_gbp) December 12, 2019
アニメ「BanG Dream! 3rd Season」OP・ED楽曲のアプリ内追加が決定😍
OP『イニシャル』
ED『夢を撃ち抜く瞬間に!』
『イニシャル』は本日21時に追加❣
Youtubeにて新情報をお届け中📣
→https://t.co/oXNcA3G8Ts#バンドリ #ガルパ pic.twitter.com/Bm9LsvcEbX
🎸#バンドリ制作発表会 速報💫
— バンドリ! ガールズバンドパーティ! (@bang_dream_gbp) December 12, 2019
現在CM放送中のタイアップ楽曲『White Afternoon』の追加が決定✨
Youtubeにて新情報をお届け中📣
→https://t.co/oXNcA3G8Ts #バンドリ #ガルパ pic.twitter.com/9G7JdxUwv6
BanG Dream! 3rd seasonのOP「イニシャル」が本日21時に追加されました。
他2曲も実装予定です。
🎸#バンドリ制作発表会 速報💫
— バンドリ! ガールズバンドパーティ! (@bang_dream_gbp) December 12, 2019
「ゆく年くる年カバー楽曲追加キャンペーン!」開催決定🎉
今後追加されるカバー楽曲のヒントを公開‼️
ぜひ予想してみてくださいね🎶
楽曲は次回「@ハロハピCiRCLE放送局」にて発表😍
Youtubeにて新情報をお届け中📣https://t.co/oXNcA3G8Ts#バンドリ #ガルパ pic.twitter.com/CvSgZJ3kxP
カバー曲キャンペーン。
Twitter上での予想は、
マクロス・Fの「ライオン」?
五等分の花嫁の「五等分の気持ち」?
「!」はいろいろ予想が別れているようです。
というか、これだけじゃわからんわ。
12月22日のハロハピ放送局で明らかになるようです。
その他、ログインキャンペーンなどが行われます。
年末年始も眠れない。
実際に組むわけではないけど、もしMac Proに対抗できる自作PCを作ったら、という前提で検討してみた。
もはやこれは男のロマンの話です。
オイラが机上で考えた構成なので、動作確認はできません。
自己責任でお願いします。
買えるとは思えませんが。
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万で作れる!(机の上の計算では)
バナークリックで応援よろしくおねがいします。
前回までの状況はこちら
最新ソースはこちら
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;
}
レコード一件ずつ参照してデータを取り出しているので、同じようにリレーションを使って部屋テーブルの部屋名を取り出している、という感じですね。
今回は難しくなかった。
残るは、部屋の競合チェック処理を変えなくちゃいけないのと、部屋でフィルタ表示させたい。
あとは部屋ごとの集計かな。
バナークリックで応援よろしくお願いします。
前回までの様子はこちら
最新ソースはこちら
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();
}
そんなにソースコードは変更していないけど、一気に進みましたね。
次回はスケジュールを部屋ごとに表示するところをやっていきます。
バナークリックで応援よろしくお願いします。
自分のTwitterアカウントもフォロワー数2300とありがたい数字になっているのですが、
いま、問題が発生しておりまして、
もっとフォロワーを増やしたいのですが、これ以上フォローできない、という事態に陥ってまして、
というのも、ツイッターの制限で、フォロワー数が一定以上いかないと、フォロー数が5000で制限されてしまうのです。
これを解決するためには、昔フォローしたけど見る価値のないアカウントのフォロー解除を行わなければなりません。
ここでいう、見る価値のないアカウントというのは、しばらくツイートしていない、いわゆる休眠アカウントと呼ばれるアカウントです。
でも、それを区別するのは、いつものツイッタークライアントでは非常に難しい。
というわけで、ツイッター管理ツールというのが必要になるわけです。
オイラが検索して見つけたのは、SocialDogというツイッター管理ツール。
本来、企業のツイッターアカウントを管理するためのツールなのですが、一般ユーザーでも機能制限付きで無料で使用できます。
便利なのがフォロー管理という機能で、この画面で、相互フォローしているアカウント、フォローしているけどフォローバックされていないアカウント(片思いアカウント)、フォローしていないフォロワー(ファンアカウント)がリスト化して表示されているのです。
便利なのが、休眠アカウントをリスト表示してくれる機能。
もちろんこの画面からフォロー解除することもできます。
こういったツールってホント便利ですよね。
Twitterアカウントがあれば簡単にアカウント登録できるのも嬉しいですよね。
こういう情報、もっとたくさんの人に伝われ。
バナークリックで応援よろしくお願いします。
こちらの記事でも書きましたが、
大方、予想通りでした。
気になる価格についてです。#MiNote10 は52,800円(税別)で本日12月9日からプレセール開始です。実際の販売開始は12月16日からとなります。
— Xiaomi Japan (@XiaomiJapan) December 9, 2019
また #MiNote10Pro も同じく本日からプレセール開始で価格は64,800円(税別)です。実際の販売開始は12月23日からとなります。 pic.twitter.com/waYfJeDkAQ
Mi Note 10とMi Note 10 Proを日本市場に投入です。
購入はAmazonで購入できます。
通常とProの違いは主にメモリの容量とストレージの容量ですね。
ミドルレンジでこの価格でこの容量はかなりお得感があります。
ちなみに残念ながらFelica(おサイフケータイ)には対応していないようです。
最高のカメラ、最高のデザイン、そして
— Xiaomi Japan (@XiaomiJapan) December 9, 2019
最高のパフォーマンス。
#DareToDiscover with #MiNote10 pic.twitter.com/oJv6cXTYZu
バナークリックで応援よろしくお願いします。
次の課題は「部屋を増設し、部屋別に管理を行う」というものでした。
今までは部屋は一つの前提で作ってきたので、これを改造する必要があります。
たぶん、テーブルはこんな感じで大丈夫だと思う。
どうせ集計時に全部結合されるんだから。
データベースの作成。マイグレーションを追加します。
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かと。
次回は予約登録時に部屋を指定する仕組みを作成します。
バナークリックで応援よろしくお願いします。