-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(shopping-cart): Ability to make transactions (#11)
BREAKING CHANGE: payloads across the project please review the docs Besides was added a cron job looking for inactive shopping carts.
- Loading branch information
Showing
27 changed files
with
568 additions
and
76 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
node_modules/ | ||
.env | ||
.env | ||
coverage | ||
.nyc_output |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
const CartService = require('../services/cart'); | ||
const InventoryService = require('../services/inventory'); | ||
const asyncUtil = require('../lib/async'); | ||
const { errorBuilder } = require('../lib/errors'); | ||
|
||
const Cart = { | ||
getTotal: cart => { | ||
return cart.products | ||
.map(product => product.quantity * product.product.price) | ||
.reduce((prev, curr) => prev + curr, 0); | ||
}, | ||
create: asyncUtil(async (req, res, next) => { | ||
const cart = await CartService.create({ user: req.user.id }); | ||
if (!cart) { | ||
throw errorBuilder({ | ||
name: 'ValidationError', | ||
message: 'Cart already existent' | ||
}); | ||
} | ||
|
||
res.status(201).json({ success: true, cart }); | ||
}), | ||
read: asyncUtil(async (req, res, next) => { | ||
const cart = await CartService.read({ user: req.user.id }); | ||
if (!cart) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Cart not found' | ||
}); | ||
} | ||
res.status(200).json({ success: true, cart }); | ||
}), | ||
update: asyncUtil(async (req, res, next) => { | ||
const item = req.body; | ||
|
||
const inventory = await InventoryService.read({ product: item.id }); | ||
if (!inventory) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Inventory not found' | ||
}); | ||
} | ||
|
||
const quantityByUserId = inventory.reservations | ||
.map(r => (r._id == req.user.id ? r.quantity : 0)) | ||
.reduce((prev, curr) => prev + curr, 0); | ||
|
||
const oldQuantity = inventory.quantity + quantityByUserId; | ||
const totalQuantity = item.quantity - oldQuantity; | ||
|
||
const payload = { | ||
quantity: item.quantity, | ||
id: item.id, | ||
delta: totalQuantity | ||
}; | ||
|
||
const inventoryUpdated = await InventoryService.update( | ||
req.user.id, | ||
payload | ||
); | ||
if (!inventoryUpdated) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Not enough product' | ||
}); | ||
} | ||
|
||
let cart; | ||
if (item.quantity <= 0) { | ||
await InventoryService.deleteProduct(req.user.id, item); | ||
cart = await CartService.removeProduct(req.user.id, item); | ||
} else { | ||
cart = await CartService.update(req.user.id, item); | ||
} | ||
if (!cart) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Product not available' | ||
}); | ||
} | ||
|
||
res.status(200).json({ success: true, cart }); | ||
}), | ||
delete: asyncUtil(async (req, res, next) => {}) | ||
}; | ||
|
||
module.exports = Cart; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
const EventService = require('../services/event'); | ||
const asyncUtil = require('../lib/async'); | ||
const { errorBuilder } = require('../lib/errors'); | ||
|
||
const Event = { | ||
create: asyncUtil(async (req, res, next) => { | ||
const event = await EventService.create(req.body); | ||
if (!event) { | ||
throw errorBuilder({ | ||
name: 'ValidationError', | ||
message: 'Problem creating the event' | ||
}); | ||
} | ||
res.status(201).json({ success: true, event }); | ||
}), | ||
read: asyncUtil(async (req, res, next) => { | ||
const event = await EventService.read({}); | ||
if (!event) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Event not found' | ||
}); | ||
} | ||
res.status(200).json({ success: true, event }); | ||
}), | ||
readAll: asyncUtil(async (req, res, next) => { | ||
const events = await EventService.readAll({ page: 1, limit: 10 }); | ||
res.status(200).json({ success: true, events }); | ||
}), | ||
update: asyncUtil(async (req, res, next) => { | ||
const payload = req.body; | ||
const event = await EventService.update(req.params.id, payload); | ||
if (!event) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Event not found' | ||
}); | ||
} | ||
res.status(200).json({ success: true, event }); | ||
}), | ||
delete: asyncUtil(async (req, res, next) => { | ||
const event = await EventService.delete(req.params.id); | ||
console.log(event); | ||
if (!event) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Event not found' | ||
}); | ||
} | ||
res.status(204).json(); | ||
}) | ||
}; | ||
|
||
module.exports = Event; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const InventoryService = require('../services/inventory'); | ||
const asyncUtil = require('../lib/async'); | ||
const { errorBuilder } = require('../lib/errors'); | ||
|
||
// TODO: Populate the right response, not only showing the ID's | ||
const Inventory = { | ||
read: asyncUtil(async (req, res, next) => { | ||
const inventory = await InventoryService.read({ product: req.params.id }); | ||
if (!inventory) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'Inventory not found' | ||
}); | ||
} | ||
res.status(200).json({ success: true, inventory }); | ||
}), | ||
readAll: asyncUtil(async (req, res, next) => { | ||
const inventory = await InventoryService.readAll({ page: 1 }); | ||
res.status(200).json({ success: true, inventory }); | ||
}) | ||
}; | ||
|
||
module.exports = Inventory; |
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
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
const VenueService = require('../services/venue'); | ||
const asyncUtil = require('../lib/async'); | ||
const { errorBuilder } = require('../lib/errors'); | ||
|
||
const Venue = { | ||
create: asyncUtil(async (req, res, next) => { | ||
const venue = await VenueService.create(req.body); | ||
if (!venue) { | ||
throw errorBuilder({ | ||
name: 'ValidationError', | ||
message: 'Problem creating the venue' | ||
}); | ||
} | ||
res.status(201).json({ success: true, venue }); | ||
}), | ||
read: asyncUtil(async (req, res, next) => { | ||
const venue = await VenueService.read({}); | ||
if (!venue) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'venue not found' | ||
}); | ||
} | ||
res.status(200).json({ success: true, venue }); | ||
}), | ||
readAll: asyncUtil(async (req, res, next) => { | ||
// TODO: use parameters for handle page and limit | ||
const venues = await VenueService.readAll({ page: 1, limit: 10 }); | ||
res.status(200).json({ success: true, venues }); | ||
}), | ||
update: asyncUtil(async (req, res, next) => { | ||
const payload = req.body; | ||
const venue = await VenueService.update(req.params.id, payload); | ||
if (!venue) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'venue not found' | ||
}); | ||
} | ||
res.status(200).json({ success: true, venue }); | ||
}), | ||
delete: asyncUtil(async (req, res, next) => { | ||
const venue = await VenueService.delete(req.params.id); | ||
if (!venue) { | ||
throw errorBuilder({ | ||
name: 'NotFoundError', | ||
message: 'venue not found' | ||
}); | ||
} | ||
res.status(204).json(); | ||
}) | ||
}; | ||
|
||
module.exports = Venue; |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const CronJob = require('cron').CronJob; | ||
const CartService = require('../services/cart'); | ||
|
||
const job = new CronJob('* */10 * * * *', function() { | ||
const cutOffDate = new Date(); | ||
cutOffDate.setMinutes(cutOffDate.getMinutes() - 1); | ||
CartService.watcherExpiration(cutOffDate); | ||
}); | ||
|
||
job.start(); | ||
|
||
module.exports = job; |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
const mongoose = require('mongoose'); | ||
const mongoosePaginate = require('mongoose-paginate'); | ||
|
||
const { Schema } = mongoose; | ||
|
||
const EventSchema = new Schema( | ||
{ | ||
venue: { | ||
type: Schema.Types.ObjectId, | ||
ref: 'Venue', | ||
required: true | ||
} | ||
}, | ||
{ timestamps: true } | ||
); | ||
|
||
EventSchema.plugin(mongoosePaginate); | ||
|
||
module.exports = mongoose.model('Event', EventSchema); |
Oops, something went wrong.