new signup for students working

parent b882e826
/* global Student, PictoCore, VStuLastInstruction, StuPicto, StuSup, sailsTokenAuth, sails, /* global Student, PictoCore, VStuLastInstruction, StuPicto, StuSup, sailsTokenAuth, sails,
Picto */ Picto */
const generatePassword = require('password-generator');
/** /**
/* StudentController /* StudentController
* *
...@@ -182,7 +184,6 @@ module.exports = { ...@@ -182,7 +184,6 @@ module.exports = {
resolve(params.license_number); resolve(params.license_number);
else { else {
License.newTrial(params.id_sup, function(err, license) { License.newTrial(params.id_sup, function(err, license) {
console.log(license.number);
if (err) if (err)
reject(err); reject(err);
else else
...@@ -193,45 +194,88 @@ module.exports = { ...@@ -193,45 +194,88 @@ module.exports = {
.then((license_number) => { .then((license_number) => {
// Check license // Check license
License.isActivable(license_number, function(err) { return new Promise(function(resolve, reject) {
if (err) { License.isActivable(license_number, function(err) {
return res.badRequest(err.message); if (err)
} reject(err)
else
resolve(license_number);
});
});
})
.then((license_number) => {
return new Promise(function(resolve, reject) {
Student.genUsername(params.name, params.surname, function(username) {
resolve({username: username, license_number: license_number});
});
});
})
.then((info) => {
// Create student
var stuData = {
name: params.name,
surname: params.surname,
password: generatePassword(),
username: info.username,
lang: params.lang
};
Student.create(stuData)
.then(function(created) {
sails.log.debug('Student ' + created.id + ' created: ' + JSON.stringify(created));
// Activate license
License.activate(info.license_number, created.id, function(err, license) {
if (err) {
Student.destroy({id: created.id});
return res.badRequest(err);
}
// Create student created = created.toJSON();
Student.create(params) created.license = license.toObject();
.then(function(created) {
sails.log.debug('Student ' + created.id + ' created: ' + JSON.stringify(created));
// Activate license // Link to supervisor
License.activate(license_number, created.id, function(err, license) { StuSup.create({student: created.id, supervisor: params.id_sup})
if (err) { .then((stu_sup) => {
if (!stu_sup) {
Student.destroy({id: created.id}); Student.destroy({id: created.id});
return res.badRequest(err); return res.serverError("Unable to link to supervisor");
} }
created = created.toJSON(); //
created.license = license.toObject(); // Send sockets messages
//
// Link to supervisor const socketToOmit = (req.isSocket) ? req.socket : undefined;
StuSup.create({student: created.id, supervisor: params.id_sup}) const linkSupervisorToStudentEvent = sails.hooks.events.linkSupervisorToStudent(
.then((stu_sup) => { stu_sup.supervisor,
if (!stu_sup) { stu_sup.student
Student.destroy({id: created.id}); );
return res.serverError("Unable to link to supervisor"); sails.hooks.events.broadcastEvent(
} sails.hooks.rooms.supervisor(stu_sup.supervisor),
return res.ok(created); linkSupervisorToStudentEvent,
}) socketToOmit
.catch((err) => { );
Student.destroy({id: created.id}); sails.hooks.events.broadcastEvent(
throw err sails.hooks.rooms.student(stu_sup.student),
}); linkSupervisorToStudentEvent,
socketToOmit
);
// return OK
return res.ok(created);
})
.catch((err) => {
Student.destroy({id: created.id});
throw err
}); });
})
.catch(function(err) {
sails.log.debug(err.message);
return res.serverError(err.message);
}); });
})
.catch(function(err) {
sails.log.debug(err.message);
return res.serverError(err.message);
}); });
}) })
.catch((err) => {res.serverError(err)}); .catch((err) => {res.serverError(err)});
...@@ -876,9 +920,11 @@ module.exports = { ...@@ -876,9 +920,11 @@ module.exports = {
.then(function(scene){ .then(function(scene){
if(!scene) if(!scene)
throw new Error("Scene not found"); throw new Error("Scene not found");
console.log("scene ID: " + scene.id)
Scene.pictos(scene.id, function(err, pictos){ Scene.pictos(scene.id, function(err, pictos){
if (err) if (err)
return res.serverError("Error obtaining pictos: "+ err); return res.serverError("Error obtaining pictos: "+ err);
scene = scene.toObject();
scene.active = true; scene.active = true;
scene.pictos=pictos; scene.pictos=pictos;
return res.ok(scene); return res.ok(scene);
......
/* global Student, StuSup, sails */ /* global Student, StuSup, sails */
const bcrypt = require('bcrypt-nodejs'); const bcrypt = require('bcrypt-nodejs');
var _ = require('lodash');
/** /**
* @class Student * @class Student
...@@ -60,7 +61,7 @@ module.exports = { ...@@ -60,7 +61,7 @@ module.exports = {
lang: { lang: {
columnName: 'lang', columnName: 'lang',
type: 'string', type: 'string',
size: 2 size: 5
}, },
id_active_scene: { id_active_scene: {
columnName: 'id_active_scene', columnName: 'id_active_scene',
...@@ -629,6 +630,36 @@ module.exports = { ...@@ -629,6 +630,36 @@ module.exports = {
.catch(err => {throw err}); .catch(err => {throw err});
}) })
.catch(err => {cb(err, null)}); .catch(err => {cb(err, null)});
},
/**
* Generates a new username using name and surname
*/
genUsername: function(name, surname, callback) {
var prefix = (name + ' ' + surname).split(/\s+/).map(x => {return x.toLowerCase()[0]}).join('');
var counter = 0;
var found = true;
async.doWhilst(
function (cb) {
counter = counter + 1;
Student.findOne({username: prefix + counter})
.then((l) => {
if (!l)
found = false;
cb();
})
.catch((err) => {
found = false;
cb();
});
},
function () {
return found;
},
function () {
callback(prefix + counter);
}
);
} }
}; };
...@@ -407,7 +407,8 @@ ...@@ -407,7 +407,8 @@
"state_spontaneous": "Spontaneous", "state_spontaneous": "Spontaneous",
"state_supervised": "Supervised", "state_supervised": "Supervised",
"stop": "Stop", "stop": "Stop",
"student_account_confirm": "The new account is now available from the students list.", "student_existing_confirm": "The student's account is now available from the students list below.",
"student_new_confirm": "The new account for <b>{{ name }} {{ surname }}</b>, with serial number <tt>{{ serial }}</tt> and credential username <tt>{{ username }}</tt>, is now available from the students list. <br> Please, set password for this new account in its <a href=\"/app/#/student/{{ id_stu }}/setup\">configuration section</a>.",
"student_added": "Student added", "student_added": "Student added",
"student_already_exists": "A student with that username already exists, please try with another one", "student_already_exists": "A student with that username already exists, please try with another one",
"student_already_linked": "The student is already linked to your account", "student_already_linked": "The student is already linked to your account",
......
...@@ -405,7 +405,8 @@ ...@@ -405,7 +405,8 @@
"state_spontaneous": "Espontáneo", "state_spontaneous": "Espontáneo",
"state_supervised": "Guiado", "state_supervised": "Guiado",
"stop": "Parar", "stop": "Parar",
"student_account_confirm": "La nueva cuenta ahora está disponible en su lista de alumnos.", "student_existing_confirm": "La nueva cuenta de estudiante ahora está disponible en su lista de alumnos, abajo.",
"student_new_confirm": "La cuenta para <b>{{ name }} {{ surname }}</b>, con número de serie <tt>{{ serial }}</tt> y credencial de usuario <tt>{{ username }}</tt>, está ya disponible en su lista de estudiantes. <br>Por favor, establezca la contraseña para la nueva cuenta en la <a href=\"/app/#/student/{{ id_stu }}/setup\">sección de configuración</a> de la misma.",
"student_added": "Estudiante añadido", "student_added": "Estudiante añadido",
"student_already_exists": "Ya existe un estudiante con ese nombre de usuario. Por favor, inténtelo de nuevo con algo diferente.", "student_already_exists": "Ya existe un estudiante con ese nombre de usuario. Por favor, inténtelo de nuevo con algo diferente.",
"student_already_linked": "El estudiante ya está vinculado a su cuenta", "student_already_linked": "El estudiante ya está vinculado a su cuenta",
......
...@@ -57,11 +57,11 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl( ...@@ -57,11 +57,11 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
$scope.showForm = function () { $scope.showForm = function () {
// Reset the form // Reset the form
$scope.formdata = { $scope.formdata = {
username: '', name: '',
password: '', password: '',
password_confirm: '', password_confirm: '',
name: $translate.instant('name'), name: '',
surname: $translate.instant('surname'), surname: '',
birthdate: Date(), birthdate: Date(),
country: 'ES', country: 'ES',
gender: 'M', gender: 'M',
...@@ -94,6 +94,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl( ...@@ -94,6 +94,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
$http.post(config.backend + '/stu/license/sup/' + $rootScope.user.id, {license: $scope.formdata.license_number}) $http.post(config.backend + '/stu/license/sup/' + $rootScope.user.id, {license: $scope.formdata.license_number})
.success(function (data) { .success(function (data) {
loadStudents(); loadStudents();
$scope.confirmation_msg = $translate.instant('student_existing_confirm');
$scope.slide.rightTo('confirmation'); $scope.slide.rightTo('confirmation');
}) })
.error(function (err) { .error(function (err) {
...@@ -118,18 +119,20 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl( ...@@ -118,18 +119,20 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
$scope.addNew = function (type) { $scope.addNew = function (type) {
// set language according to interface settings // set language according to interface settings
$scope.formdata.lang = $translate.use(); $scope.formdata.lang = $rootScope.user.lang;
// Validate password match
if ($scope.formdata.password_confirm.length && $scope.formdata.password !== $scope.formdata.password_confirm) {
ngToast.danger($translate.instant('password_match'));
return;
}
// Send creating call to server // Send creating call to server
$http.post(config.backend + '/stu', $scope.formdata) $http.post(config.backend + '/stu', $scope.formdata)
.success(function (data) { .success(function (data) {
loadStudents(); loadStudents();
$scope.confirmation_msg = $translate.instant('student_new_confirm',
{
name: data.name,
surname: data.surname,
username: data.username,
serial: data.license.number,
id_stu: data.id,
});
$scope.slide.rightTo('confirmation'); $scope.slide.rightTo('confirmation');
}) })
.error(function (err) { .error(function (err) {
......
...@@ -96,17 +96,12 @@ ...@@ -96,17 +96,12 @@
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<div class="form-group"> <div class="form-group">
<label translate>username</label> <label translate>name</label>
<input type="username" class="form-control" id="setup_username" placeholder="{{ 'username_default' | translate }}" required ng-model="formdata.username" /> <input type="text" class="form-control" id="setup_name" placeholder="{{ 'name' | translate }}" required ng-model="formdata.name" />
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate>password</label> <label translate>surname</label>
<input type="password" class="form-control" id="setup_password1" placeholder="{{ 'password_new_type' | translate }}" name="password" ng-model="formdata.password" required /> <input type="text" class="form-control" id="setup_surname" placeholder="{{ 'surname' | translate }}" required ng-model="formdata.surname" />
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.new.password.$dirty && forms.new.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div>
<div class="form-group">
<input type="password" class="form-control" id="setup_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" ng-model="formdata.password_confirm" required />
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.new.password.$dirty && forms.new.password_confirm.$dirty" translate>password_match</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate>license_number</label> <label translate>license_number</label>
...@@ -140,17 +135,12 @@ ...@@ -140,17 +135,12 @@
</div> </div>
<div class="form-group col-md-4" id="office_form"> <div class="form-group col-md-4" id="office_form">
<div class="form-group"> <div class="form-group">
<label translate>username</label> <label translate>name</label>
<input type="username" class="form-control" id="setup_username" placeholder="{{ 'username_default' | translate }}" required ng-model="formdata.username" /> <input type="text" class="form-control" id="setup_name" placeholder="{{ 'name' | translate }}" required ng-model="formdata.name" />
</div>
<div class="form-group">
<label translate>password</label>
<input type="password" class="form-control" id="setup_password1" placeholder="{{ 'password_new_type' | translate }}" name="password" ng-model="formdata.password" required />
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.test.password.$dirty && forms.test.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="setup_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" ng-model="formdata.password_confirm" required /> <label translate>surname</label>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.test.password.$dirty && forms.test.password_confirm.$dirty" translate>password_match</span> <input type="text" class="form-control" id="setup_surname" placeholder="{{ 'surname' | translate }}" required ng-model="formdata.surname" />
</div> </div>
</div> </div>
</div> </div>
...@@ -173,7 +163,7 @@ ...@@ -173,7 +163,7 @@
<div ng-class="slide.back ? 'switch-animation-back' : 'switch-animation'" ng-switch-when="confirmation"> <div ng-class="slide.back ? 'switch-animation-back' : 'switch-animation'" ng-switch-when="confirmation">
<h2>{{ 'account_available' | translate }} </h2> <h2>{{ 'account_available' | translate }} </h2>
<p translate>student_account_confirm</p> <p ng-bind-html="confirmation_msg"></p>
<br> <br>
<img src="img/child.png"/> <img src="img/child.png"/>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
"no_name": "Sin nombre", "no_name": "Sin nombre",
"no_surname": "Sin apellidos", "no_surname": "Sin apellidos",
"office_link": "El centro/gabinete \"{{{ name }}}\", con correo electrónico \"{{{ email }}}\" le ha añadido como parte de su equipo.", "office_link": "El centro/gabinete \"{{{ name }}}\", con correo electrónico \"{{{ email }}}\" le ha añadido como parte de su equipo.",
"signin_mail": "Para activar su cuenta en Pictogram, primero haga click en el siguiente enlace:\n {{{ url }}} \nAcceda con su correo y la contraseña siguiente:\n {{{ password }}}\nLe recomendamos modificar la contraseña tan pronto accede al sistema.", "signin_mail": "Para activar su cuenta en Pictogram, primero haga click en el siguiente enlace:\n {{{ url }}} \nAcceda con su correo y la contraseña siguiente:\n {{{ password }}}\nLe recomendamos modificar la contraseña tan pronto acceda al sistema.",
"student_unlinked": "Se ha desvinculado de la cuenta de estudiante \"{{{ name }}} {{{ surname }}}\", con número de licencia \"{{{ license }}}\".", "student_unlinked": "Se ha desvinculado de la cuenta de estudiante \"{{{ name }}} {{{ surname }}}\", con número de licencia \"{{{ license }}}\".",
"therapist_office_request": "El/la terapeuta {{{ name }}}, con correo electrónico {{{ email }}}, pide ser asociado a algún estudiante.", "therapist_office_request": "El/la terapeuta {{{ name }}}, con correo electrónico {{{ email }}}, pide ser asociado a algún estudiante.",
"tutor_office_request": "El/la tutor/a/padre/madre {{{ name }}}, con correo electrónico {{{ email }}}, pide ser asociado a algún estudiante.", "tutor_office_request": "El/la tutor/a/padre/madre {{{ name }}}, con correo electrónico {{{ email }}}, pide ser asociado a algún estudiante.",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment