Created
April 26, 2019 02:08
-
-
Save riotrah/10463a12d9ac1193874ed2edcfef7dd1 to your computer and use it in GitHub Desktop.
Rooms Vendor Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Joi from 'joi'; | |
import moment from 'moment'; | |
import 'moment-round'; | |
import { isNumber } from 'util'; | |
import { searchRequestSchema } from './../lib/models/index'; | |
import { ValidationError } from './../lib/utils/Errors'; | |
import log from './../lib/utils/logger'; | |
export default class Vendor { | |
constructor(db, mq) { | |
this.db = db; | |
this.mq = mq; | |
} | |
get defaultAmenities() { | |
return this._amenities; | |
} | |
get hours() { | |
return this._hours; | |
} | |
get supplementaryFields() { | |
return this._supplementaryFields; | |
} | |
get shortCode() { | |
return this._shortCode; | |
} | |
get title() { | |
return this._title; | |
} | |
get canCancel() { | |
return this._canCancel; | |
} | |
get info() { | |
return { | |
defaultAmenities: this.defaultAmenities, | |
hours: this.hours, | |
supplementaryFields: this.supplementaryFields, | |
canCancel: this.canCancel, | |
shortCode: this.shortCode, | |
title: this.title, | |
}; | |
} | |
openingTime(day = moment()) { | |
return moment( | |
(this.hours[ | |
moment(day) | |
.format('ddd') | |
.toLowerCase() | |
] || this.hours['all'])[0][0], | |
'HH:mm' | |
).startOf('minutes'); | |
} | |
closingTime(day = moment()) { | |
return moment( | |
(this.hours[ | |
moment(day) | |
.format('ddd') | |
.toLowerCase() | |
] || this.hours['all'])[0][1], | |
'HH:mm' | |
).startOf('minutes'); | |
} | |
async reserve(request) { | |
const { error } = this.validateRequest(request); | |
if (error) { | |
const err = new ValidationError({ | |
message: `Reservation failed vendor requirements : ${error.message}`, | |
reason: error.reason, | |
received: request, | |
namespace: `${this.shortCode}:RESERVE`, | |
}); | |
throw err; | |
} | |
const reserveTime = moment() | |
.utc() | |
.toISOString(); | |
const locationId = this.shortCode; | |
let vendorId; | |
try { | |
vendorId = await this._reserve(request); | |
} catch (e) { | |
log.error(e); | |
const err = new VendorError(`Failed to reserve : ${e}`, 'RESERVE'); | |
throw err; | |
} | |
return request.toReservation({ vendorId, reserveTime, locationId }); | |
} | |
async search(params) { | |
const { error } = Joi.validate(params, searchRequestSchema); | |
if (error) { | |
throw new VendorValidationError({ | |
message: 'Invalid search parameters', | |
namespace: 'SEARCH', | |
reason: error.message, | |
received: params, | |
}); | |
} | |
let results; | |
try { | |
results = await this._search(params); | |
} catch (e) { | |
log.error(e); | |
throw new VendorError(`Failed vendor search : ${e}`, 'SEARCH'); | |
} | |
if (params.singleRoomPerVendor) { | |
return [ results[0] ]; | |
} else { | |
return results; | |
} | |
} | |
async listRooms(params = {}) { | |
const { amenities = [], capacity = 1 } = params; | |
return this._listRooms({ amenities, capacity: +capacity }); | |
} | |
// TODO: may have problems with vendorId vs id | |
async getRoom(vendorId) { | |
return this._getRoom(vendorId); | |
} | |
async cancel({ roomId, vendorId }) { | |
if (!this.canCancel) { | |
throw new VendorError(`${this.shortCode} does not support cancelling reservations`, 'CANCEL'); | |
} | |
return this._cancel({ roomId, vendorId }); | |
} | |
validateRequest(request) { | |
const { supplementaryFields } = request; | |
try { | |
request = request._isReservationRequest ? request : new ReservationRequest(request); | |
} catch (e) { | |
throw new ValidationError({ | |
message: 'Request invalid', | |
namespace: 'VENDOR:VALIDATE', | |
reason: e.reason, | |
received: request, | |
}); | |
} | |
const requiredVendorSuppFieldName = this.supplementaryFields.filter((f) => f.required).map((f) => f.field.name); | |
const completeRequestSuppFieldNames = supplementaryFields | |
.filter((f) => f.response && f.response !== '') | |
.map((f) => f.field.name); | |
if (!requiredVendorSuppFieldName.every((f) => completeRequestSuppFieldNames.includes(f))) { | |
return { error: { reason: 'supplementaryFields', message: `Not all required supp fields are answered` } }; | |
} | |
return { value: request }; | |
} | |
} | |
class VendorError extends Error { | |
constructor(msg, namespace) { | |
const message = `[ERROR:VENDOR:${namespace}] : ${msg}`; | |
super(message); | |
} | |
} | |
class VendorValidationError extends ValidationError { | |
constructor(params) { | |
let { namespace } = params; | |
if (!namespace) { | |
namespace = 'VENDOR'; | |
} else { | |
namespace = 'VENDOR:' + namespace; | |
} | |
super({ ...params, namespace }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment