diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..40b878d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules/
\ No newline at end of file
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..e9a2fac
--- /dev/null
+++ b/app.js
@@ -0,0 +1,22 @@
+const express = require('express');
+const bodyParser = require('body-parser');
+const app = express();
+// const models = require('./models');
+
+app.use(bodyParser.json());
+app.set('view engine', 'ejs');
+app.use(bodyParser.urlencoded({
+ extended: false
+}));
+
+const menu = require('./routes/menu')
+const restaurant = require('./routes/restaurant')
+
+app.get('/', (req, res) => {
+ res.send('Hello Word')
+});
+
+app.use('/menus', menu);
+app.use('/restaurants', restaurant);
+
+app.listen(3000, () => console.log(`The App listening on port 3000!`));
\ No newline at end of file
diff --git a/config/config.json b/config/config.json
new file mode 100644
index 0000000..a92e0ef
--- /dev/null
+++ b/config/config.json
@@ -0,0 +1,9 @@
+{
+ "development": {
+ "username": "postgres",
+ "password": "postgres",
+ "database": "platinum_livecode4",
+ "host": "127.0.0.1",
+ "dialect": "postgres"
+ }
+}
diff --git a/helper/format_currency.js b/helper/format_currency.js
new file mode 100644
index 0000000..4fb19dc
--- /dev/null
+++ b/helper/format_currency.js
@@ -0,0 +1,5 @@
+function format_currency(num) {
+ return num.toLocaleString()
+}
+
+module.exports = format_currency
\ No newline at end of file
diff --git a/migrations/20180301021557-create-restaurant.js b/migrations/20180301021557-create-restaurant.js
new file mode 100644
index 0000000..62007ca
--- /dev/null
+++ b/migrations/20180301021557-create-restaurant.js
@@ -0,0 +1,30 @@
+'use strict';
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.createTable('Restaurants', {
+ id: {
+ allowNull: false,
+ autoIncrement: true,
+ primaryKey: true,
+ type: Sequelize.INTEGER
+ },
+ name: {
+ type: Sequelize.STRING
+ },
+ address: {
+ type: Sequelize.TEXT
+ },
+ createdAt: {
+ allowNull: false,
+ type: Sequelize.DATE
+ },
+ updatedAt: {
+ allowNull: false,
+ type: Sequelize.DATE
+ }
+ });
+ },
+ down: (queryInterface, Sequelize) => {
+ return queryInterface.dropTable('Restaurants');
+ }
+};
\ No newline at end of file
diff --git a/migrations/20180301021744-create-menu.js b/migrations/20180301021744-create-menu.js
new file mode 100644
index 0000000..1214453
--- /dev/null
+++ b/migrations/20180301021744-create-menu.js
@@ -0,0 +1,36 @@
+'use strict';
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.createTable('Menus', {
+ id: {
+ allowNull: false,
+ autoIncrement: true,
+ primaryKey: true,
+ type: Sequelize.INTEGER
+ },
+ name: {
+ type: Sequelize.STRING
+ },
+ menu_type: {
+ type: Sequelize.STRING
+ },
+ rating: {
+ type: Sequelize.INTEGER
+ },
+ price: {
+ type: Sequelize.STRING
+ },
+ createdAt: {
+ allowNull: false,
+ type: Sequelize.DATE
+ },
+ updatedAt: {
+ allowNull: false,
+ type: Sequelize.DATE
+ }
+ });
+ },
+ down: (queryInterface, Sequelize) => {
+ return queryInterface.dropTable('Menus');
+ }
+};
\ No newline at end of file
diff --git a/migrations/20180301024403-addcolumn_reataurant.js b/migrations/20180301024403-addcolumn_reataurant.js
new file mode 100644
index 0000000..756ec0a
--- /dev/null
+++ b/migrations/20180301024403-addcolumn_reataurant.js
@@ -0,0 +1,23 @@
+'use strict';
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ /*
+ Add altering commands here.
+ Return a promise to correctly handle asynchronicity.
+
+ Example:
+ */
+ return queryInterface.addColumn('Menus', 'id_restaurant', { type: Sequelize.INTEGER });
+ },
+
+ down: (queryInterface, Sequelize) => {
+ /*
+ Add reverting commands here.
+ Return a promise to correctly handle asynchronicity.
+
+ Example:
+ return queryInterface.dropTable('users');
+ */
+ }
+};
diff --git a/models/index.js b/models/index.js
new file mode 100644
index 0000000..5662f10
--- /dev/null
+++ b/models/index.js
@@ -0,0 +1,36 @@
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+var Sequelize = require('sequelize');
+var basename = path.basename(__filename);
+var env = process.env.NODE_ENV || 'development';
+var config = require(__dirname + '/../config/config.json')[env];
+var db = {};
+
+if (config.use_env_variable) {
+ var sequelize = new Sequelize(process.env[config.use_env_variable], config);
+} else {
+ var sequelize = new Sequelize(config.database, config.username, config.password, config);
+}
+
+fs
+ .readdirSync(__dirname)
+ .filter(file => {
+ return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
+ })
+ .forEach(file => {
+ var model = sequelize['import'](path.join(__dirname, file));
+ db[model.name] = model;
+ });
+
+Object.keys(db).forEach(modelName => {
+ if (db[modelName].associate) {
+ db[modelName].associate(db);
+ }
+});
+
+db.sequelize = sequelize;
+db.Sequelize = Sequelize;
+
+module.exports = db;
diff --git a/models/menu.js b/models/menu.js
new file mode 100644
index 0000000..b0d0902
--- /dev/null
+++ b/models/menu.js
@@ -0,0 +1,79 @@
+'use strict';
+module.exports = (sequelize, DataTypes) => {
+ const Op = sequelize.Op
+ var Menu = sequelize.define('Menu', {
+ name: DataTypes.STRING,
+ menu_type: {
+ type: DataTypes.STRING,
+ validate: {
+ isIn: {
+ args: ['food', 'drink'],
+ msg: "isi menu type dengan food / drink!"
+ },
+ // isUpdate: (value, option) => {
+ // console.log('-----------', value)
+ // Menu.findOne({
+ // where: {
+ // menu_type: {
+ // [Op.ne]: value,
+ // }
+ // }
+ // })
+ // .then(data => {
+ // console.log('sini');
+ // console.log(data.id,'-----=+++++++++');
+ // if (data.menu_type === value) {
+ // next()
+ // } else {
+ // next('isi menu type dengan food / drink!')
+ // }
+
+ // })
+ // .catch(err => {
+ // console.log('sana')
+ // })
+ // }
+ }
+ },
+ rating: DataTypes.INTEGER,
+ price: DataTypes.STRING,
+ id_restaurant: {
+ type: DataTypes.INTEGER,
+ validate: {
+ checkRes: (value, next) => {
+ Menu.findAll({
+ where: {
+ id_restaurant: value
+ }
+ })
+ .then(data => {
+ if (data.length > 4) {
+ console.log(data.length, '----------------------')
+ next(`Varian Food sudah maksimal !`)
+ } else {
+ next()
+ }
+ })
+ .catch(err => {
+ console.log(err)
+ })
+ }
+ }
+ }
+ }, {
+ hooks: {
+ beforeCreate: (value, option) => {
+ if (value.menu_type == 'food' && value.price == 0) {
+ value.price = 15000
+ }
+ if (value.menu_type == 'drink' && value.price == 0) {
+ value.price = 10000
+ }
+ }
+ }
+ });
+ Menu.associate = function(models) {
+ Menu.belongsTo(models.Restaurant, { foreignKey: 'id_restaurant'} )
+ };
+ return Menu;
+};
\ No newline at end of file
diff --git a/models/restaurant.js b/models/restaurant.js
new file mode 100644
index 0000000..1aaa379
--- /dev/null
+++ b/models/restaurant.js
@@ -0,0 +1,12 @@
+'use strict';
+module.exports = (sequelize, DataTypes) => {
+ var Restaurant = sequelize.define('Restaurant', {
+ name: DataTypes.STRING,
+ address: DataTypes.TEXT
+ }, {});
+ Restaurant.associate = function(models) {
+ Restaurant.hasMany(models.Menu, { foreignKey: 'id_restaurant' })
+
+ };
+ return Restaurant;
+};
\ No newline at end of file
diff --git a/routes/menu.js b/routes/menu.js
new file mode 100644
index 0000000..b8333fa
--- /dev/null
+++ b/routes/menu.js
@@ -0,0 +1,102 @@
+const router = require('express').Router()
+const { Menu, Restaurant } = require('../models');
+
+router.get('/', (req,res) => {
+ Menu.findAll({
+ include: Restaurant
+ })
+ .then(data => {
+ Restaurant.findAll()
+ .then(dataRes => {
+ // console.log(data)
+ let err = null
+ res.render('menu', { data, dataRes, err, helper: require('../helper/format_currency') })
+ })
+ .catch(err => {
+ console.log(err)
+ })
+ })
+ .catch(err => {
+ console.log(err)
+ })
+});
+
+router.post('/', (req,res) => {
+ let dataAddObj = {
+ name: req.body.name,
+ menu_type: req.body.menu_type,
+ rating: req.body.rating,
+ price: req.body.price,
+ id_restaurant: req.body.id_restaurant
+ }
+ Menu.create(dataAddObj)
+ .then(success => {
+ res.redirect('/menus')
+ })
+ .catch(err => {
+ Menu.findAll({
+ include: Restaurant
+ })
+ .then(data => {
+ Restaurant.findAll()
+ .then(dataRes => {
+ res.render('menu', { data, dataRes, err, helper: require('../helper/format_currency') })
+ console.log(err)
+ })
+ })
+ })
+});
+
+router.get('/:id/edit', (req,res) => {
+ Menu.findById(req.params.id)
+ .then(data => {
+ Restaurant.findAll()
+ .then(dataRes => {
+ console.log(data)
+ res.render('edit_menu', { data, dataRes })
+ })
+ .catch(err => {
+ console.log(err)
+ })
+ })
+ .catch(err => {
+ console.log(err)
+ })
+});
+
+router.post('/:id/edit', (req, res) => {
+ let dataEditObj = {
+ name: req.body.name,
+ menu_type: req.body.menu_type,
+ rating: req.body.rating,
+ price: req.body.price,
+ id_restaurant: req.body.id_restaurant
+ }
+ Menu.update(dataEditObj, {
+ where : {
+ id: req.params.id
+ }
+ })
+ .then(data => {
+ res.redirect('/menus')
+ })
+ .catch(err => {
+ console.log(err)
+ })
+});
+
+router.get('/:id/delete', (req,res) => {
+ Menu.destroy({
+ where: {
+ id: req.params.id
+ }
+ })
+ .then(data => {
+ res.redirect('/menus')
+ })
+ .catch(err => {
+ console.log(err)
+ })
+})
+
+module.exports = router
\ No newline at end of file
diff --git a/routes/restaurant.js b/routes/restaurant.js
new file mode 100644
index 0000000..2e2a0f8
--- /dev/null
+++ b/routes/restaurant.js
@@ -0,0 +1,65 @@
+const router = require('express').Router()
+const { Menu, Restaurant } = require('../models');
+
+router.get('/', (req, res) => {
+ Restaurant.findAll()
+ .then(dataRes => {
+ let err = null
+ res.render('restaurant', { dataRes})
+ })
+ .catch(err => {
+ console.log(err)
+ })
+ .catch(err => {
+ console.log(err)
+ })
+});
+
+router.get('/:id/view_menu', (req,res) => {
+ Menu.findAll({
+ where: {
+ id_restaurant: req.params.id
+ }
+ })
+ .then(data => {
+ Restaurant.findById(req.params.id)
+ .then(dataRes => {
+ console.log(data)
+ res.render('view_menu', { data, dataRes, helper: require('../helper/format_currency') })
+ })
+ .catch(err => {
+ console.log(err)
+ })
+ })
+})
+
+router.post('/:id/search', (req,res) => {
+ console.log(req.params.id);
+ console.log(req.body.type_search);
+ console.log(req.body.input);
+ var query = null
+ if (req.body.type_search === 'name') {
+ query = 'name';
+ } else if (req.body.type_search === 'menu_type') {
+ query = 'menu_type'
+ } else if (req.body.type_search === 'rating') {
+ query = 'rating'
+ } else {
+ query = 'price'
+ }
+
+ // Menu.findAll({
+ // where: {
+ // query: req.body.input
+ // }
+ // })
+ // .then(dataSearch => {
+ // console.log(dataSearch)
+ // })
+ // .catch(err => {
+ // console.log(err)
+ // })
+})
+
+
+module.exports = router
\ No newline at end of file
diff --git a/seeders/20180301021931-insert_restaurant.js b/seeders/20180301021931-insert_restaurant.js
new file mode 100644
index 0000000..8db676a
--- /dev/null
+++ b/seeders/20180301021931-insert_restaurant.js
@@ -0,0 +1,46 @@
+'use strict';
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ /*
+ Add altering commands here.
+ Return a promise to correctly handle asynchronicity.
+
+ Example:
+ return queryInterface.bulkInsert('Person', [{
+ name: 'John Doe',
+ isBetaMember: false
+ }], {});
+ */
+ return queryInterface.bulkInsert('Restaurants', [
+ {
+ name: 'KFC',
+ address: 'Jakarta Timur',
+ createdAt: new Date(),
+ updatedAt: new Date()
+ },
+ {
+ name: 'Pizza Hut',
+ address: 'Jakarta Pusat',
+ createdAt: new Date(),
+ updatedAt: new Date()
+ },
+ {
+ name: 'Dons Burger',
+ address: 'Jakarta Barat',
+ createdAt: new Date(),
+ updatedAt: new Date()
+ }
+ ], {});
+ },
+
+ down: (queryInterface, Sequelize) => {
+ /*
+ Add reverting commands here.
+ Return a promise to correctly handle asynchronicity.
+
+ Example:
+ return queryInterface.bulkDelete('Person', null, {});
+ */
+ }
+};
diff --git a/views/edit_menu.ejs b/views/edit_menu.ejs
new file mode 100644
index 0000000..eb9fd57
--- /dev/null
+++ b/views/edit_menu.ejs
@@ -0,0 +1,32 @@
+
+
+
+
+
+ Page Title
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/views/menu.ejs b/views/menu.ejs
new file mode 100644
index 0000000..4ea61ef
--- /dev/null
+++ b/views/menu.ejs
@@ -0,0 +1,68 @@
+
+
+
+
+
+ View Menu
+
+
+
+
+
+ Menu
+
+
+
+ Id |
+ Name |
+ Menu Type |
+ Rating |
+ Price |
+ Restaurant_Id |
+ Action |
+
+
+
+ <%data.map(val => {%>
+
+ <%= val.id %> |
+ <%= val.name %> |
+ <%= val.menu_type %> |
+ <%= val.rating %> |
+ <%= helper(Number(val.price)) %> |
+ <%= val.Restaurant.name %> |
+
+ Edit
+ Delete
+ |
+
+ <%})%>
+
+
+
+
+
+
+ <% if (err) { %>
+ <%= err %>
+ <% } %>
+
+
+
+
\ No newline at end of file
diff --git a/views/restaurant.ejs b/views/restaurant.ejs
new file mode 100644
index 0000000..4bd7d48
--- /dev/null
+++ b/views/restaurant.ejs
@@ -0,0 +1,39 @@
+
+
+
+
+
+ Page Title
+
+
+
+
+
+
+ Restaurant
+
+
+
+ Id |
+ Name |
+ Address |
+ Action |
+
+
+
+ <%dataRes.map(val => {%>
+
+ <%= val.id %> |
+ <%= val.name %> |
+ <%= val.address %> |
+
+ View Menu
+ |
+
+ <%})%>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/views/view_menu.ejs b/views/view_menu.ejs
new file mode 100644
index 0000000..ac0c162
--- /dev/null
+++ b/views/view_menu.ejs
@@ -0,0 +1,55 @@
+
+
+
+
+
+ Page Title
+
+
+
+
+
+
+
+ Menu Restaurant: <%= dataRes.name %>
+
+
+
+
+
+
+
+
+ Id |
+ Name |
+ Menu Type |
+ Rating |
+ Price |
+
+
+
+ <%data.map(val => {%>
+
+ <%= val.id %> |
+ <%= val.name %> |
+ <%= val.menu_type %> |
+ <%= val.rating %> |
+ <%= helper(Number(val.price)) %> |
+
+ <%})%>
+
+
+
+
+
+
\ No newline at end of file