Skip to content

Instantly share code, notes, and snippets.

@joshbedo
Created June 1, 2017 21:57
Show Gist options
  • Save joshbedo/6d6350cbf0d5a2ac21c62208cba26b6c to your computer and use it in GitHub Desktop.
Save joshbedo/6d6350cbf0d5a2ac21c62208cba26b6c to your computer and use it in GitHub Desktop.
Checkout Route Handlers
import Joi from 'joi';
import {sanitizeEmailAddress} from '../../core/email';
import {ErrorName} from '../../core/errors';
import {BadRequest} from '../../core/responses';
import {hasKeys} from '../../core/utils';
import {Cart} from '../carts/models';
import log from './logging';
import {Checkout} from './models';
import {CheckoutSerializer} from './serializers';
/**
* API handlers for Checkout endpoints
*/
class CheckoutsHandler {
/**
* Process POST request
* Create a new checkout
*/
static async post(request, reply) {
// Validate cart permissions
let cart;
try {
cart = await Cart.getIfAllowed(request.payload.cartId, request.auth.credentials, request.query.accessToken);
if (!cart) {
return reply(BadRequest.invalidParameters('payload', {cartId: ['Invalid']})).code(400);
} else if (cart.archived === true) {
return reply(BadRequest.invalidParameters('payload', {cartId: ['Archived']})).code(400);
}
} catch (err) {
if (err.name === ErrorName.PERMISSION_DENIED) {
return reply(BadRequest.invalidParameters('payload', {cartId: ['Invalid']})).code(400);
} else {
log.error({where: 'CheckoutsHandler.post'}, 'Unable to get cart');
log.error(err);
return reply().code(500);
}
}
// Cart must have products
if (!cart.products || cart.products.length === 0) {
return reply(BadRequest.invalidParameters('payload', {'cart.products': ['Cannot be empty']})).code(400);
}
// Create checkout
let checkout = await Checkout.create(request.payload);
return reply(await new CheckoutSerializer(checkout).serialize()).code(201);
}
}
/**
* API handlers for Checkout ID endpoint
*/
class CheckoutIdHandler {
/**
* Process GET request
* Return checkout with given ID
*/
static async get(request, reply) {
// Appropriate permission validations should have been done in route prerequisites
return reply(await new CheckoutSerializer(request.pre.checkout).serialize());
}
/**
* Process PATCH request
* Partial updates of a given Checkout
*/
static async patch(request, reply) {
// Appropriate permission validations should have been done in route prerequisites
let checkoutId = request.pre.checkout.id;
let checkout;
// Check if cart is archived
if (request.pre.checkout.archived === true) {
return reply(BadRequest.invalidParameters('payload', {checkout: ['Archived']})).code(400);
}
// Validate payload and make respective updates
if (hasKeys(request.payload, ['userId'])) {
if (request.payload.userId === '') {
return reply(BadRequest.invalidParameters('payload', {userId: ['This field is required']})).code(400);
} else {
cart = await Cart.updateUserId(cartId, request.payload.userId);
}
} else if (hasKeys(request.payload, ['mergeId'])) {
if (request.payload.mergeId === '') {
return reply(BadRequest.invalidParameters('payload', {mergeId: ['This field is required']})).code(400);
} else {
let mergeCart = await Cart.get(request.payload.mergeId);
if (mergeCart.userId !== request.auth.credentials.id) {
return reply(BadRequest.invalidParameters('payload', {mergeId: ['Invalid']})).code(400);
} else if (mergeCart.archived === true) {
return reply(BadRequest.invalidParameters('payload', {mergeId: ['Archived']})).code(400);
} else {
cart = await Cart.merge(cartId, mergeCart, true);
}
}
} else if (hasKeys(request.payload, ['archive'])) {
if (request.payload.archive === true) {
cart = await Cart.archive(cartId);
}
} else if (hasKeys(request.payload, ['product'])) {
if (!request.payload.product.hasOwnProperty('id') || request.payload.product.id === '') {
return reply(BadRequest.invalidParameters('payload', {'product.id': ['This field is required']})).code(400);
} else if (!request.payload.product.hasOwnProperty('quantity') || request.payload.product.quantity === '') {
return reply(BadRequest.invalidParameters('payload', {'product.quantity': ['This field is required']})).code(400);
} else if (isNaN(parseInt(request.payload.product.quantity))) {
return reply(BadRequest.invalidParameters('payload', {'product.quantity': ['Must be an integer']})).code(400);
} else {
let product = await Product.get(request.payload.product.id);
if (!product || product.enabled !== true) {
return reply(BadRequest.invalidParameters('payload', {'product.id': ['Invalid']})).code(400);
} else if (product.stock < request.payload.product.quantity) {
return reply(BadRequest.invalidParameters('payload', {'product.quantity': ['Not enough in stock']})).code(400);
} else {
cart = await Cart.updateProduct(cartId, request.payload.product.id, request.payload.product.quantity);
}
}
} else {
return reply({message: 'Invalid payload'}).code(400);
}
return reply(await new CartSerializer(cart).serialize());
}
}
export {CheckoutsHandler, CheckoutIdHandler};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment