#施設、建物
export interface Prop {
//----------const
id: number;
na: string;
roomTyps: number[];//洋室、和室、キャンプ、バンガロー等const ROOMTYPのid
path: string;//ドメインnegura.gq
lat: number;//googleMap
lng: number;//googleMap
zoom: number;//googleMap
marker: number;//googleMap
icon: string;
users: string[];//編集権限のあるuserId
txts: string[];//トップページのスライダーに表示
//-----------MySQL
price: number;//入場料
charges: Charge[];//駐車料等他の料金
close: boolean;//休止
idx: number;//並び順
}
ドメイン名に一致するpathを持つpropがシステム単位になる。
###部屋タイプ
export const ROOMTYP = {
1: { na: '洋室' },
2: { na: '和室' },
3: { na: 'ドミトリー' },
4: { na: 'バンガロー' },
5: { na: 'キャンプ' }
}
変更することはほとんどないので定数としてconfigファイルにベタ書き
#部屋、区画
export interface Room {
id: number;
prop: number;//建物、施設id
typ: number;//ROOMTYP 和室、洋室、キャンプ、バンガローなど
na: string;
txt: string;//説明文
img: string;
simg: string;
limg: string;
price: number;//基本価格
charges:Charge[];//追加人、車等への課金
qty: number;//在庫、部屋数
size: number;//フリーサイト面積上限
created: Date;
chat: boolean;//true=チャット口コミ書込み可
close: boolean;//true=休止中
idx: number;//並び順
beds24: boolean;//true=OTA連携
beds24id: number;//beds24のroomId
max_people?: number;//↓beds24 params
max_adult?: number;
max_child?: number;
min_stay?: number;
max_stay?: number;
min_price?: number;
}
基本となる貸出単位
###雑費
export interface Charge {
id: number;
prop: number;
room: number;
key: string;
typ: string;//people,vehicle,tent...etc
min: number;
max: number;
price: number;
idx: number;//並び順
}
人数追加料、こども料金、駐車料、テント代など
#予約料金算出クラス
export class Unit {
adult: number;
child: number;
vehicles: Vehicle[];
constructor(adult?: number, child?: number, vehicles?: Vehicle[]) {
this.adult = adult ? adult : 2;
this.child = child ? child : 0;
this.vehicles = vehicles ? vehicles : [{ id: 1, size: VEHICLETYP[1].size }];
}
protected toObj(array: any[]) {//[{id:x,...}]arrayからidでグループ化したcountを値に持つObject({x:count})を返す
let data: any = {};
for (let v of array) {
if (data[v.id]) {
data[v.id]++;
} else {
data[v.id] = 1;
}
}
return data;
}
size(): number {
let size = this.adult * 10 + this.child * 5;
for (let vehicle of this.vehicles) {
size += vehicle.size;
}
return size;
}
toString(): { people: string, vehicle: string } {
let people = this.adult ? `大人:${this.adult}人 ` : "";
people += this.child ? `こども:${this.child}人 ` : "";
let vehicle = "";
const obj = this.toObj(this.vehicles);
Object.keys(obj).forEach(id => {
vehicle += `${VEHICLETYP[id].na}:${obj[id]}台 `;
})
return { people: people, vehicle: vehicle };
}
price(room): number {
let price = this.adult * room.price_adult + this.child * room.price_child;
for (let vehicle of this.vehicles) {
price += room[`price_${VEHICLETYP[vehicle.id].key}`];
}
return price;
}
queryParams(): Object {//ページ遷移時のクエリストリング生成用
let params: any = {};
if (this.adult) params.adult = this.adult;
if (this.child) params.child = this.child;
const obj = this.toObj(this.vehicles);
Object.keys(obj).forEach(id => {
params[VEHICLETYP[id].key] = obj[id];
})
return params;
}
}
予約料金はroomオブジェクトをpriceメソッドに入れて算出する。
現在のpriceメソッドはChargeに対応していない。
昨日いただいたレビュー
「今後の拡張性を考慮すると、可変部分(課金対象は人?車?テント?、上限面積は?、等)は別クラスに分割しておいた方が、例えば別のキャンプ場に売る時などに、テストの範囲を限定できるかと思いました。」
を実現すべくChargeクラスを新設した。
######元のroomオブジェクト
export interface Room {
id: number;
prop: number;//建物、施設id
typ: number;//ROOMTYP 和室、洋室、キャンプ、バンガローなど
na: string;
txt: string;//説明文
img: string;
simg: string;
limg: string;
price: number;//標準価格
qty: number;//在庫
size: number;//フリーサイト面積上限
created: Date;
chat: boolean;//true=チャット口コミ書込み可
close: boolean;//true=休止中
idx: number;//並び順
beds24: boolean;//true=OTA連携
beds24id: number;//beds24のroomId
max_people?: number;
max_adult?: number;
max_child?: number;
min_stay?: number;
max_stay?: number;
min_price?: number;
price_adult?: number;
price_child?: number;
price_car?: number;
price_motorcycle?: number;
price_bycycle?: number;
}
雑費をroomに直接並べていくのは拡張性を考えると避けるべきか?
###乗り物(雑費Charge.typのひとつ)
export const VEHICLETYP = {
0: { na: "", key: "", icon: "", size: 0 },
1: { na: '車', key: "car", icon: "http://maps.google.co.jp/mapfiles/ms/icons/cabs.png", size: 10 },
2: { na: 'バイク', key: "motorcycle", icon: "http://maps.google.co.jp/mapfiles/ms/icons/motorcycling.png", size: 5 },
3: { na: '自転車', key: "bicycle", icon: "http://maps.google.co.jp/mapfiles/ms/icons/cycling.png", size: 3 },
4: { na: 'トレーラー', key: "trailer", icon: "http://maps.google.co.jp/mapfiles/ms/icons/truck.png", size: 15 }
}
あまり変更することがないと思い定数にしたが、sizeは頻繁な変更が必要かも?
Vehicleを配列にした理由は、UIにsegment
https://ionicframework.com/jp/docs/api/segment
を使用したかったため。
利用者のほとんどは車1台、乗り物複数台は稀なので、乗り物の種類ごとに数を入力させるのではなく、乗り物の種類を選んでもらうというアプローチ。
車2台は上のように表現され少々不自然だが、さらに最下部の+ボタンでいくつでも追加できる。ほとんどの人にとっては今後乗り物の種類が増えてもUXが低下しない。
おかげでtoObj([])という余計なprotectedメソッドが必要になるが。
というわけで、これからUnitクラスのprice()メソッドをChargeオブジェクトに対応するよう改修していきます...