aboutsummaryrefslogblamecommitdiffstatshomepage
path: root/app/controllers/system.js
blob: a09f51714eff94b572f10aa3b6450bfb19a8015a (plain) (tree)
1
2
3
4
5
6
7
8
9
10



                      
 
                                  
                                               
                                                   

                                       
                                 












                                                                                             
                                                                                                           


                      
 




                                                                  




          
                                    




                                                                                                                     
 

 



             

                                  

                      

       

 



                 

                                      

                        

       

 
 




                                                                  




                   
                                        
 
                                           
                              



                                                                                                                                                                                                                               
                                                                       
                                                           
                                                                                                                           
 
                            
                                  

                                                                                               
                                            

                                                                                                                      




                                                                


                                                                                                            

                                                                                                                               

                                               


                                               

                                                                       
                                                                   
                                                                                                                                   













                                                                                                                

                   
           
       
 

 



                                

                                      
                                                            
                                                                
                                                                                                                                 

                                    

                                                                                                                               

                                         

                                                                                                                                   








                                                                                                                                 
                                                                  






                                                                                                                                                  
                                            

                                     

                                                                                    














                                                                                           

                                                                                       

                                                                 

                                                                                              
                 
 
                                               





                                       
                            
                   
               
           
       

 
 





                                      
                                                  
                                           
                              


                                                                                                                                                                                                                               
 



                                        

 
 



                            
                                          
 

                                                                                                                           
                              





                                    
       
 
 
 


                             

                                              
 
                 


                                                                                             

                                  
                               
                                                                                                                                                       
 
                                                                
                                                                                                                           
 
                          
                                                                                







                                                                                                          




                                                                                                                             
 
                                      
                                                                                                                                                       
                                                                    
               
           

       





                     
                                         
                              



                                                                                                                                                                                                                               



                                      

 




                      
                                             
                              



                                                                                                                                                                                                                               
                                        
                                
                                

                                    
                                                                                                                                                        
         



                                      
                               


                                        



                                                            


                                              
       
 

 
 



                                     
                                                

                    

                                                                                                                           

                                            


                                                                                                                                   
 
                                                             
                                                                                                                                      
 
                                                                                

                                               

                                                                                                                                           
 








                                                                                                                                     

/**
 * Module dependencies
 */

var mongoose = require('mongoose')
  , env = process.env.NODE_ENV || 'development'
  , config = require('../../config/config.js')[env]
  , Project = mongoose.model('Project')
  , Access = mongoose.model('Access')
  , User = mongoose.model('User')
  , pPost = mongoose.model('pPost')
  , Validator = require('validator').Validator
  , v = new Validator()
  , sanitize = require('validator').sanitize;


// validation error handling. This collects all errors before pushing them out in getErrors()
Validator.prototype.error = function(msg) {
    this._errors.push(msg);
    return this;
}
Validator.prototype.getErrors = function() {
    var returnThis = this._errors;
    this._errors = ''; // need to reset errors between sessions because of object model that retains errors
    return returnThis;
}


/**
 * Before the user log in
 * ===============================================================
*/


/**
 * GET '/'
 */

exports.index = function(req, res) {
    if (req.user !== undefined) return res.redirect('/dashboard'); // if the user is logged in, redirect to dashboard
    res.render('index', {
        title: 'Divid'
      , user:req.user
    });
}


/**
 * GET '/faq'
 */

exports.faq = function(req, res) {
    res.render('faq', {
        title: 'FAQ'
      , user: req.user
    });
}


/**
 * GET '/contact'
 */

exports.contact = function(req, res) {
    res.render('contact', {
        title: 'Kontakt'
      , user: req.user
    });
}



/**
 * After the user has logged in
 * ===============================================================
*/


/**
 * GET '/dashboard'
 */

exports.dashboard = function(req, res) {

    // check if user is actually registered
    if (req.user.status < 3) {
        if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); }
        else { return res.redirect('back'); }
    }

    // start by loading all the projects the current user has access to
    Access.loadUser(req.user._id, function(err, projects) {
        if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

        var projectIDs = [];
        var pro = { project: [] };

        // Time to initiate some projects so we can calculate how much the user owes / is owned
        projects.forEach(function(project) {
            projectIDs.push(project.project._id); // fills an array with all the project IDs
            pro.project[project.project._id] = { // initiates an object for each project, where we can store some data
                total:  0  // total for project
              , user:   0  // what req-user has spent on project
              , users:  0  // number of users on project
            };
        });

        // loads all the users for the projects the current user has access to
        // this is necessary so we can calculate what the user owes based on how many users each project has
        Access.loadProjects(projectIDs, function(err, participants) {
            if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

            // counts the users in each project
            participants.forEach(function(p) {
                pro.project[p.project].users++;
            });

            // loads ALL posts for EVERY project the user has access to
            pPost.loadByProjects(projectIDs, function(err, posts) {
                if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

                // FUN FUN FUN CALCULATIONS
                posts.forEach(function(p) {
                    if (String(p.user._id) === String(req.user._id)) pro.project[p.project._id].user += p.value;
                    pro.project[p.project._id].total += p.value;
                });

                res.render('dashboard', {
                    title: 'Dashboard'
                  , user: req.user
                  , projects: projects
                  , posts: posts
                  , participants: participants
                     , pro: pro
                });
            });
        });
    });
}


/**
 * GET '/project/:short'
 * :short = shortURL for project
 */

exports.project = function(req, res) {
    // loads the project based on the :short part of the url
    Project.loadShort(req.params.short, function(err, project) {
        if (err || !project) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err });

        //loads all users in project
        Access.loadProject(project._id, function(err, access) {
            if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

            // loads all posts in project
            pPost.loadProject(project._id, function(err, posts) {
                if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

                // ALRIGHT! This is where the FUN starts!

               // first we create an object that will hold all the calculational data
                var pro = {
                        users:  0   // number of users
                      , user:   []  // this array will contain every user. Every user will then have it's own object inside this.
                      , total:  0   // the overall total.
                      , each:   0   // what each person has to pay
                      , otot:   0   // how much is owned in total!
                    };

                // then we calculate how many users we have, and initiate objects foreach user
                access.forEach(function(a) {
                    if (String(a.user._id) === String(req.user._id)) req.user.permissions = a.permissions; //sets YOUR permissions in this project

                    pro.users++;
                    pro.user[a.user._id] = {
                            total:  0
                          , diff:   0
                          , coeff:  0   // the coefficient of hom much you are owned
                          , name:   a.user.name
                        };
                });

                // now we must collect all the money!
                posts.forEach(function(p) {
                    pro.total += parseFloat(p.value);
                    pro.user[p.user._id].total += parseFloat(p.value);
                });

                // then calculate how much each user must pay in total
                pro.each = pro.total / pro.users;

                // then calculate how much each person owe and is owned
                for(var i in pro.user) {
                    pro.user[i].diff = parseFloat(pro.user[i].total - pro.each).toFixed(2);
                    if (pro.user[i].diff > 0) pro.otot += parseFloat(pro.user[i].diff);
                }

                // sets the coefficient if the user is owed money
                for (var i in pro.user) {
                    if (pro.user[i].diff > 0) pro.user[i].coeff = pro.user[i].diff / pro.otot;
                }

                res.render('project/project', {
                    title: project.name
                  , user: req.user
                  , req: req
                  , project: project
                  , access: access
                  , posts: posts
                  , pro: pro
                });
            });
        });
    });
}


/**
 * GET '/project/:short/participants'
 *
 * POST is in app/controllers/users.js
 */

exports.projectParticipants = function(req, res) {
    // check if user is actually registered
    if (req.user.status < 3) {
        if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); }
        else { return res.redirect('back'); }
    }

    res.render('project/participants', {
        title: 'Prosjektdeltakere'
      , user: req.user
    });
}


/**
 * GET '/projet/:short/post'
 */

exports.projectPost = function(req, res) {

    Project.loadShort(req.params.short, function(err, project) {
        if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });
        req.project = project;
        res.render('project/post', {
            title: 'Legg til utgift'
          , user: req.user
          , req: req
          , project: project
        });
    });
}


/**
 * POST '/project:short/post'
 */

exports.postProjectPost = function(req, res) {

    // Validation
    v.check(req.body.project, 'The project was lost').notEmpty();
    v.check(req.body.what, 'You need to fill in the what-field').notEmpty();
    v.check(req.body.value, 'The value must be a positive number').notEmpty().isInt().min(0);

    // error when validation fails
    var errors = v.getErrors();
    if (errors.length !== 0) return res.status(500).render('error', { title: '500', text: 'Det oppstod en valideringsfeil ' + errors, error: errors });

    Project.loadShort(req.params.short, function(err, project) {
        if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

        // check if access
        Access.checkAccess(req.user._id, project._id, 0, function(err, access) {
            if (err || !access) return res.status(403).render('error', { title: '403', text: 'no sir.' });

            // Time to fill in the model!
            var ppost = new pPost();

            ppost.user         = req.user._id;
            ppost.for          = req.user._id;
            ppost.project      = project._id;
            ppost.what         = sanitize(req.body.what).escape();
            ppost.comment      = sanitize(req.body.comment).xss(); // xss will remove cross-site-scripting in the textfield.
            ppost.participants = sanitize(req.body.participants).escape();
            ppost.value        = sanitize(req.body.value).toInt(); // this will remove leading zeroes. '0123' => '123'
            ppost.when         = new Date(sanitize(req.body.date).escape() + ' ' + sanitize(req.body.time).escape() + ':00');

            ppost.save(function(err) {
                if (err) return res.render('project/post', { title: 'Legg til utgift - en feil oppstod', user: req.user, req: req, project: project });
                return res.redirect('/project/' + project.shortURL);
            });
        });
    });
}


/**
 * GET '/project/new'
 */

exports.newProject = function(req, res) {
    if (req.user.status < 3) {
        if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); }
        else { return res.redirect('back'); }
    }

    res.render('project/newProject', {
        title: 'Nytt prosjekt'
      , user: req.user
    });
}


/**
 * POST '/project/new'
 */

exports.postNewProject = function(req, res) {
    if (req.user.status < 3) {
        if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); }
        else { return res.redirect('back'); }
    }

    var project = new Project(req.body);
    project.user = req.user._id;
    project.save(function(err) {
        if (err) {
            console.log(err.errors);
            return res.render('project/newProject', { title: 'Nytt prosjekt - en feil oppstod', user: req.user, errors: err.errors, project: project });
        }
        var access = new Access();
        access.user = req.user._id;
        access.creator = req.user._id;
        access.project = project._id;
        access.permissions = 9;
        access.save(function(err) {
            if (err) {
                console.log(err.errors);
                return res.render('project/newProject', {
                    title: 'Nytt prosjekt - en feil oppstod'
                  , user: req.user
                });
            }
            return res.redirect('/dashboard');
        });
    });

}


/**
 * GET '/project/:short/delete/:post'
 */

exports.deleteProjectPost = function(req, res) {

    //Locate project
    Project.findOne({ shortURL: req.params.short }).select('_id').exec(function(err, project) {
        if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

        //make sure you actually have access
        Access.findOne({project: project._id, user: req.user._id}, function(err, access) {
            if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });
            if (!access) return res.status(403).render('error', { title: '403', text: 'Du har ikke tilgang til å gjøre dette' });

            pPost.load(req.params.post, function(err, post) {
                if (err || !post) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err });

                if (post.user._id === req.user._id || access.permissions >= 6) {

                    // delete! (only if access)
                    pPost.remove({ _id: post._id }, function(err) {
                        if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack });

                        return res.redirect('back');
                    })
                } else { return res.status(403).render('error', { title: '403', text: 'Du har ikke tilgang til å gjøre dette' }); }
            })
        })
    });
}