Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node Course Test: Pablo Velazquez #6

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ const bodyParser = require("body-parser");
const morgan = require("morgan");
const mongoose = require("mongoose");
const config = require("./config");
const {responseHelpers} = require("./middleware");
let globalCache = []
const {responseHelpers,cacheMiddleware} = require("./middleware")(globalCache,config);
const routes = require("./routes");
const request = require("request");



require("./models");

const app = express();
Expand All @@ -22,15 +27,15 @@ app.use(morgan("dev"));
app.use(responseHelpers);

// Add cache middleware
// app.use(cacheMiddleware);
app.use(cacheMiddleware);

// Setup mongoose and load models
mongoose.Promise = global.Promise;
mongoose.connect(config.db, {useNewUrlParser: true});
// models(mongoose);

// Register the routes and mount them all at /api
app.use("/api", routes(app, express.Router()));
app.use("/api", routes(app, express.Router(),request));

// default route handler
app.use((req, res) => {
Expand Down
5 changes: 4 additions & 1 deletion config/dev.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module.exports = {
env: "dev",
db: "mongodb://localhost:27017/courses",
port: process.env.PORT || 8000
port: process.env.PORT || 8000,
ignoreCacheRoutes: [
"/api/admin/billing/getChargeableStudents"
]
};
5 changes: 4 additions & 1 deletion config/prod.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module.exports = {
env: "prod",
db: "mongodb://localhost:27017/courses",
port: process.env.PORT || 80
port: process.env.PORT || 80,
ignoreCacheRoutes: [
"/api/admin/billing/getChargeableStudents"
]
};
5 changes: 4 additions & 1 deletion config/test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module.exports = {
env: "test",
db: "mongodb://localhost:27017/courses_test",
port: process.env.PORT || 3000
port: process.env.PORT || 3000,
ignoreCacheRoutes: [
"/api/admin/billing/getChargeableStudents"
]
};
75 changes: 73 additions & 2 deletions controllers/billing.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = (mongoose) => {
module.exports = (mongoose,request, config) => {
const Course = mongoose.model("Course");
const Evaluation = mongoose.model("Evaluation");
const Student = mongoose.model("Student");
Expand Down Expand Up @@ -82,7 +82,78 @@ module.exports = (mongoose) => {
});
}

function _parseBillingAddress({street1,city,state,country}){
return `${country}, ${state}, ${city}, ${street1}`;
}

function _getChargeableStudents(req, res, url) {

return new Promise( (resolve,reject ) => {
request.get(url+'/api/admin/billing/getChargeableStudents', (err,_,data) => {
if (err)
reject(err)
try {
const students = JSON.parse(data).data.studentsBillingInfo;
resolve(students);
}
catch (err) {
reject(err)
}
})
})
}

function _generateInvoiceAFIP(student,url,json = null){
return new Promise( (resolve,reject) => {
if (!json) {
json = {
nomYAp: `${student.firstName}' '${student.lastName}`,
dir: _parseBillingAddress(student.address),
importe: parseFloat(student.price / 100)
}
}
request.post(url+'/api/afip', {json:json}, (err,_, data) => {
if (err){
return reject(err)
}

if (data.status === 'success') {
return resolve({BillingNumber:data.data.id,
FirstAndLastName: json.nomYAp,
Address:json.dir,
price:student.price
})
}
console.log("AFIP fallo, Reintentando...",data);
_generateInvoiceAFIP(student,url,json)
.then( data => resolve(data))
.catch( err => reject(err) )
})
})
}

function getInvoices(req, res) {
const url = req.protocol + '://' + req.hostname + ':' + config.port;
_getChargeableStudents(req, res, url)
.then (students => {
let invoicesPromise = [];
students.forEach ( student => {
invoicesPromise.push(_generateInvoiceAFIP(student,url));
});
return Promise.all(invoicesPromise);
})
.then ( invoices => {
res.response200(invoices, `Found '${invoices.length}' Invoices.`);
})
.catch (err => {
res.response500(err, "Error on get Chargeable Students");
})


}

return {
getChargeableStudents
getChargeableStudents,
getInvoices
};
};
2 changes: 1 addition & 1 deletion controllers/courses.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = (mongoose) => {
var Course = mongoose.model("Course"),
filterFields = ["status"],
filterFields = ["status","technologyId"],
sortFields = ["status"];

var buildFilterQuery = function(params) {
Expand Down
5 changes: 4 additions & 1 deletion controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ const CoursesController = require("./courses");
const StudentsController = require("./students");
const EvaluationsController = require("./evaluations");
const TechnologiesController = require("./technologies");
const StatsController = require("./stats");


module.exports = {
BillingController,
EvaluationsController,
CoursesController,
StudentsController,
TechnologiesController
TechnologiesController,
StatsController
};
61 changes: 61 additions & 0 deletions controllers/stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module.exports = (mongoose,request, config) => {
const Evaluation = mongoose.model("Evaluation");
const Student = mongoose.model("Student");

/**
* failuresByStates - Lists the failures by state.
*
* @param {type} req description
* @param {type} res description
* @return {Array<State,Number>} data
*/
function failuresByStates(req, res) {
Evaluation.find({'notes.status':'failed'}).populate('students')
.then(evaluations => {

//Iterates over evaluations
const students = evaluations.reduce( (retArray, curr) => {
//Iterates over notes and build a StudentID array
const aux = curr.notes.reduce( (retArray, item) => {
if (item.status === 'failed')
return retArray.concat(item.studentId)
else
return retArray
}, [] );
return retArray.concat(aux);
}, [] );

return students;
})
.then( students => {
console.log(students);
//Now we need to populate students addresses
Student.find({'_id': { $in: students}})
.then( students => {

//reduce student array to <State,Number> array
const states = students.reduce( (obj, curr) => {

if (curr.billingAddress && curr.billingAddress.state){
if (obj[curr.billingAddress.state])
obj[curr.billingAddress.state] = obj[curr.billingAddress.state] + 1
else{
obj[curr.billingAddress.state] = 1;
}
}

return obj;
}, {})

res.response200(states);
})
})
.catch((err) => {
res.response500(err, "evaluations couldn't be found!");
});
}

return {
failuresByStates
};
};
69 changes: 69 additions & 0 deletions middleware/cacheMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@


module.exports = (globalCache,config) => {

return (req, res, next) => {

//Check ignore cache routes config
if (!config.ignoreCacheRoutes || config.ignoreCacheRoutes.indexOf(req.originalUrl) === -1) {

if (req.method == "GET") {

//Check if resource alredy requested
if (globalCache[req.originalUrl]) {
//Found! then return it
console.log('Resource found in Cache')
return res.json(globalCache[req.originalUrl]);
}

//Overrides response200 to store data on success
res.response200 = (data = {}, message = "ok") => {
const json = {data, status: "success", message};
globalCache[req.originalUrl] = json;
res.json(json);
};
}

if (req.method === "POST" || req.method === "PUT") {


//Removes from cache this resource and all related requests
Object.entries(globalCache).forEach(([key,value], idx) => {

let drop = false;
let url = req.url;

//Removes entries in find
if (req.method === "PUT") {
//Get id by parsing string because req.params.id isnt available here!
const urlSplit = url.split("/")
if ( key === url )
drop = true;

//patch url variable
urlSplit.pop()
url = urlSplit.join("/")
}

//Removes entries in list
if ( !drop && key === url)
drop = true;

//Removes entries in list with queries
if ( key.includes(`${url}?`) )
drop = true;

if ( drop )
delete globalCache[key] ;
});

}
}
else {
console.log('Ignoring cache on route '+req.originalUrl)
}

next();
}

};
10 changes: 8 additions & 2 deletions middleware/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
const responseHelpers = require("./responseHelpers");
module.exports = (globalCache,config) => {
const responseHelpers = require("./responseHelpers");
const cacheMiddleware = require("./cacheMiddleware")(globalCache,config);

module.exports = {responseHelpers};
return {
responseHelpers,
cacheMiddleware
}
};
15 changes: 12 additions & 3 deletions routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const {
EvaluationsController,
CoursesController,
StudentsController,
TechnologiesController
TechnologiesController,
StatsController,
} = require("./controllers");
const afipAPI = require("./services/afip-mock-api");

Expand All @@ -20,13 +21,15 @@ function mapGenericControllerRoutes(controllers, router) {
});
}

module.exports = (app, router) => {
module.exports = (app, router, request) => {
const mongoose = app.get("mongoose");
const courseController = CoursesController(mongoose);
const studentController = StudentsController(mongoose);
const evaluationController = EvaluationsController(mongoose);
const technologyController = TechnologiesController(mongoose);
const billingController = BillingController(mongoose);
const billingController = BillingController(mongoose, request, app.get("config"));
const statsController = StatsController(mongoose);


const controllers = [
{basePath: "/evaluations", controller: evaluationController},
Expand All @@ -43,5 +46,11 @@ module.exports = (app, router) => {
router.route("/afip")
.post(afipAPI.getInvoice);

router.route("/admin/billing/getInvoices")
.get(billingController.getInvoices);

router.route("/stats/failuresByStates")
.get(statsController.failuresByStates)

return router;
};
Loading