Skip to content

Instantly share code, notes, and snippets.

@riotrah
Created April 26, 2019 02:08
Show Gist options
  • Save riotrah/10463a12d9ac1193874ed2edcfef7dd1 to your computer and use it in GitHub Desktop.
Save riotrah/10463a12d9ac1193874ed2edcfef7dd1 to your computer and use it in GitHub Desktop.
Rooms Vendor Class
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