const express = require('express'); const path = require('path'); const CrudModule = require('../../base/CrudModule'); const RepositorySystem = require('../../systems/RepositorySystem'); const RoutingSystem = require('../../systems/RoutingSystem'); const Actions = require('../../systems/ActionSystem'); const UserMiddleware = require('./UserFilter.js'); let OrderScheme = { fields: [ { key: "amount", type: "decimal" }, { key: "products", type: "text" }, { key: "user_id", type: "integer", fk: { "table": "users", "key": "id" } } ] }; class OrderModule extends CrudModule { constructor(){ super('/orders', [1,1,1,1,1], 'Orders', '', [UserMiddleware]); this.repository = RepositorySystem.create('Orders', OrderScheme); this.productsRepo = RepositorySystem.create('Products'); this.paymentRepo = RepositorySystem.create('Payment'); this.setRepo(this.repository); // this.users = RepositorySystem.create('Users'); // You can get any repo you want!! this.router = express.Router(); this.init(); } init() { let routes = [ { type: 'custom', method: 'post', endpoint: '/submit', customFn: this.verifyOrder.bind(this) }, { type:'custom', method:'post', endpoint:'/some/', customFn: (req,res) => { this._checkProds(req.body.products) .then((result) => { console.log(result) res.sendStatus(200) }) .catch((e) => { res.send("Something went wrong") }) } } ] RoutingSystem.loadRoutes(routes, this.router, '/orders', [UserMiddleware]); } //1 check user --> Authentication Ok (200) //2 check products availability //3 Check shipping method and payment method //4 save Order as a row in Order Table //5 Update products Table with correct quantities //check Products Availability _checkPayment(payment_id){ return new Promise((resolve,reject) =>{ this.paymentRepo.get('id',payment_id) .then((res) => { console.log(res) resolve(res) }) }).catch((e)=> { reject(e) }) } _checkShipping(shipping_id){ } submitOrder(order) { let tOrder = {...order}; tOrder.products = JSON.stringify(tOrder.products); return this.clearObject(tOrder).then((temp) => this.repository.insert(temp)); } verifyOrder(req, res) { let order = req.body; // check order fields are filled! // get products and check quantity! console.log("Verifying order"); //get products if we have enough quantity let proms = order.products.map((item) => { let id = item.id; let quantity = item.quantity; let price = item.price; return this.productsRepo.get('id', id) .then((prod) => { if(prod[0].quantity < quantity) { throw Error(`Product with id: ${id} is low on quantity`); } else if ( prod[0].price !== price ) { throw Error(`Product with id: ${id} has different price than reported | price : ${prod[0].price} | reported : ${price}`); } return prod[0]; }); }); //update products table Actions.emit('verifyOrder', order) // run other verifications .then((order) => Promise.all(proms) // check quantities .then((array) => { // check total let total = parseFloat((order.products.reduce((total, item) => total + (item.price * item.quantity), 0) + order.shipping_cost).toFixed(2)); if (order.amount !== total) { throw Error(`Order Amount different from calculated ${order.amount} -> ${total}`); } if(!req.user.id) { throw Error(`No user ?!`); } order["user_id"] = req.user.id; return order; }) ) .then((order) => this.submitOrder(order)) // submit .then(() => { // update Warehouse let promises = order.products.map((item) => { return this.productsRepo.get('id', item.id) .then((data) => { data[0].quantity = data[0].quantity - item.quantity; return this.productsRepo.update(item.id, data[0]); }); }); return Promise.all(promises); }) .then((data) => console.log(data)) .then((data) => { res.status(200).send({ success: true }) }) .catch((e) => { console.log(e); res.sendStatus(400) }); } } module.exports = OrderModule;