Archived
2

Merge pull request #8 in ~VLE2FE/dfop-api from status to develop

* commit '806b77eecf2e0f24e65a604b2c6f6d736e5e2903':
  adjusted material
  adjusted sample
  adjusted condition
This commit is contained in:
Veit Lukas (PEA4-Fe) 2020-05-13 14:19:00 +02:00
commit c84d0ebf0c
19 changed files with 294 additions and 105 deletions

View File

@ -34,6 +34,7 @@ info:
<li>0: newly added/changed</li> <li>0: newly added/changed</li>
<li>10: validated</li> <li>10: validated</li>
</ul> </ul>
<a href="https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/dfop-api/">Bitbucket repository</a>
# TODO: Link to new documentation page # TODO: Link to new documentation page

View File

@ -4,6 +4,7 @@
get: get:
summary: condition by id summary: condition by id
description: 'Auth: all, levels: read, write, maintain, dev, admin' description: 'Auth: all, levels: read, write, maintain, dev, admin'
x-doc: status handling (accessible (only for maintain/admin))? # TODO
tags: tags:
- /condition - /condition
responses: responses:
@ -24,6 +25,7 @@
put: put:
summary: change condition summary: change condition
description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to reference samples created by another user' description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to reference samples created by another user'
x-doc: status is reset to 0 on any changes
tags: tags:
- /condition - /condition
security: security:
@ -61,6 +63,7 @@
delete: delete:
summary: delete condition summary: delete condition
description: 'Auth: basic, levels: write, maintain, dev, admin' description: 'Auth: basic, levels: write, maintain, dev, admin'
x-doc: sets status to -1
tags: tags:
- /condition - /condition
security: security:
@ -83,6 +86,7 @@
post: post:
summary: add condition summary: add condition
description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to reference samples created by another user' description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to reference samples created by another user'
x-doc: 'Adds status: 0 automatically'
tags: tags:
- /condition - /condition
security: security:

View File

@ -2,6 +2,7 @@
get: get:
summary: lists all materials summary: lists all materials
description: 'Auth: all, levels: read, write, maintain, dev, admin' description: 'Auth: all, levels: read, write, maintain, dev, admin'
x-doc: returns only materials with status 10 # TODO: methods /materials/new|deleted
tags: tags:
- /material - /material
responses: responses:
@ -24,6 +25,7 @@
get: get:
summary: get material details summary: get material details
description: 'Auth: all, levels: read, write, maintain, dev, admin' description: 'Auth: all, levels: read, write, maintain, dev, admin'
x-doc: status handling (accessible (only for maintain/admin))? # TODO
tags: tags:
- /material - /material
responses: responses:
@ -42,6 +44,7 @@
put: put:
summary: change material summary: change material
description: 'Auth: basic, levels: write, maintain, dev, admin' description: 'Auth: basic, levels: write, maintain, dev, admin'
x-doc: status is reset to 0 on any changes
tags: tags:
- /material - /material
security: security:
@ -72,6 +75,7 @@
delete: delete:
summary: delete material summary: delete material
description: 'Auth: basic, levels: write, maintain, dev, admin' description: 'Auth: basic, levels: write, maintain, dev, admin'
x-doc: sets status to -1
tags: tags:
- /material - /material
security: security:
@ -94,6 +98,7 @@
post: post:
summary: add material summary: add material
description: 'Auth: basic, levels: write, maintain, dev, admin' description: 'Auth: basic, levels: write, maintain, dev, admin'
x-doc: 'Adds status: 0 automatically'
tags: tags:
- /material - /material
security: security:

View File

@ -2,8 +2,9 @@
parameters: parameters:
- $ref: 'api.yaml#/components/parameters/Id' - $ref: 'api.yaml#/components/parameters/Id'
get: get:
summary: TODO measurement values by id summary: measurement values by id
description: 'Auth: all, levels: read, write, maintain, dev, admin' description: 'Auth: all, levels: read, write, maintain, dev, admin'
x-doc: status handling (accessible (only for maintain/admin))? # TODO
tags: tags:
- /measurement - /measurement
responses: responses:
@ -57,6 +58,7 @@
delete: delete:
summary: delete measurement summary: delete measurement
description: 'Auth: basic, levels: write, maintain, dev, admin' description: 'Auth: basic, levels: write, maintain, dev, admin'
x-doc: sets status to -1
tags: tags:
- /measurement - /measurement
security: security:

View File

@ -2,6 +2,7 @@
get: get:
summary: all samples in overview summary: all samples in overview
description: 'Auth: all, levels: read, write, maintain, dev, admin' description: 'Auth: all, levels: read, write, maintain, dev, admin'
x-doc: returns only samples with status 10 # TODO: methods /samples/new|deleted
tags: tags:
- /sample - /sample
responses: responses:
@ -23,6 +24,7 @@
get: get:
summary: TODO sample details summary: TODO sample details
description: 'Auth: all, levels: read, write, maintain, dev, admin' description: 'Auth: all, levels: read, write, maintain, dev, admin'
x-doc: status handling (accessible (only for maintain/admin))? # TODO
tags: tags:
- /sample - /sample
responses: responses:
@ -43,6 +45,7 @@
put: put:
summary: change sample summary: change sample
description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to edit samples created by another user' description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to edit samples created by another user'
x-doc: status is reset to 0 on any changes
tags: tags:
- /sample - /sample
security: security:
@ -73,6 +76,7 @@
delete: delete:
summary: delete sample summary: delete sample
description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to edit samples created by another user' description: 'Auth: basic, levels: write, maintain, dev, admin <br>Only maintain and admin are allowed to edit samples created by another user'
x-doc: sets status to -1, notes and references to this sample are also kept, only note_fields are updated accordingly
tags: tags:
- /sample - /sample
security: security:
@ -95,6 +99,7 @@
post: post:
summary: add sample summary: add sample
description: 'Auth: basic, levels: write, maintain, dev, admin' description: 'Auth: basic, levels: write, maintain, dev, admin'
x-doc: 'Adds status: 0 automatically'
tags: tags:
- /sample - /sample
security: security:
@ -125,6 +130,7 @@
get: get:
summary: list all existing field names for custom notes fields summary: list all existing field names for custom notes fields
description: 'Auth: all, levels: read, write, maintain, dev, admin' description: 'Auth: all, levels: read, write, maintain, dev, admin'
x-doc: integrity has to be ensured # TODO: implement mechanism to regularly check note_fields
tags: tags:
- /sample - /sample
responses: responses:

View File

@ -6,7 +6,8 @@ const ConditionSchema = new mongoose.Schema({
sample_id: {type: mongoose.Schema.Types.ObjectId, ref: SampleModel}, sample_id: {type: mongoose.Schema.Types.ObjectId, ref: SampleModel},
number: String, number: String,
parameters: mongoose.Schema.Types.Mixed, parameters: mongoose.Schema.Types.Mixed,
treatment_template: {type: mongoose.Schema.Types.ObjectId, ref: TreatmentTemplateModel} treatment_template: {type: mongoose.Schema.Types.ObjectId, ref: TreatmentTemplateModel},
status: Number
}); });
export default mongoose.model('condition', ConditionSchema); export default mongoose.model('condition', ConditionSchema);

View File

@ -10,7 +10,8 @@ const MaterialSchema = new mongoose.Schema({
numbers: [{ numbers: [{
color: String, color: String,
number: Number number: Number
}] }],
status: Number
}); });
export default mongoose.model('material', MaterialSchema); export default mongoose.model('material', MaterialSchema);

View File

@ -5,8 +5,8 @@ import MeasurementTemplateModel from './measurement_template';
const MeasurementSchema = new mongoose.Schema({ const MeasurementSchema = new mongoose.Schema({
condition_id: {type: mongoose.Schema.Types.ObjectId, ref: ConditionModel}, condition_id: {type: mongoose.Schema.Types.ObjectId, ref: ConditionModel},
values: mongoose.Schema.Types.Mixed, values: mongoose.Schema.Types.Mixed,
status: Number, measurement_template: {type: mongoose.Schema.Types.ObjectId, ref: MeasurementTemplateModel},
measurement_template: {type: mongoose.Schema.Types.ObjectId, ref: MeasurementTemplateModel} status: Number
}); });
export default mongoose.model('measurement', MeasurementSchema); export default mongoose.model('measurement', MeasurementSchema);

View File

@ -9,10 +9,10 @@ const SampleSchema = new mongoose.Schema({
type: String, type: String,
color: String, color: String,
batch: String, batch: String,
validated: Boolean,
material_id: {type: mongoose.Schema.Types.ObjectId, ref: MaterialModel}, material_id: {type: mongoose.Schema.Types.ObjectId, ref: MaterialModel},
note_id: {type: mongoose.Schema.Types.ObjectId, ref: NoteModel}, note_id: {type: mongoose.Schema.Types.ObjectId, ref: NoteModel},
user_id: {type: mongoose.Schema.Types.ObjectId, ref: UserModel} user_id: {type: mongoose.Schema.Types.ObjectId, ref: UserModel},
status: Number
}); });
export default mongoose.model('sample', SampleSchema); export default mongoose.model('sample', SampleSchema);

View File

@ -1,7 +1,7 @@
import should from 'should/as-function'; import should from 'should/as-function';
import ConditionModel from '../models/condition'; import ConditionModel from '../models/condition';
import TestHelper from "../test/helper"; import TestHelper from "../test/helper";
// TODO: status
describe('/condition', () => { describe('/condition', () => {
let server; let server;
@ -70,8 +70,32 @@ describe('/condition', () => {
url: '/condition/700000000000000000000001', url: '/condition/700000000000000000000001',
auth: {basic: 'janedoe'}, auth: {basic: 'janedoe'},
httpStatus: 200, httpStatus: 200,
req: {parameters: {material: 'copper', weeks: 3}}, req: {parameters: {material: 'copper', weeks: 3}}
res: {_id: '700000000000000000000001', sample_id: '400000000000000000000001', number: 'B1', treatment_template: '200000000000000000000001', parameters: {material: 'copper', weeks: 3}} }).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '700000000000000000000001', sample_id: '400000000000000000000001', number: 'B1', treatment_template: '200000000000000000000001', parameters: {material: 'copper', weeks: 3}});
ConditionModel.findById('700000000000000000000001').lean().exec((err, data) => {
if (err) return done(err);
should(data).have.property('status', 10);
done();
});
});
});
it('keeps only one unchanged parameter', done => {
TestHelper.request(server, done, {
method: 'put',
url: '/condition/700000000000000000000001',
auth: {basic: 'janedoe'},
httpStatus: 200,
req: {parameters: {material: 'copper'}}
}).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '700000000000000000000001', sample_id: '400000000000000000000001', number: 'B1', treatment_template: '200000000000000000000001', parameters: {material: 'copper', weeks: 3}});
ConditionModel.findById('700000000000000000000001').lean().exec((err, data) => {
if (err) return done(err);
should(data).have.property('status', 10);
done();
});
}); });
}); });
it('changes the given properties', done => { it('changes the given properties', done => {
@ -86,9 +110,11 @@ describe('/condition', () => {
should(res.body).be.eql({_id: '700000000000000000000001', sample_id: '400000000000000000000001', number: 'B1', treatment_template: '200000000000000000000001', parameters: {material: 'hot air', weeks: 10}}); should(res.body).be.eql({_id: '700000000000000000000001', sample_id: '400000000000000000000001', number: 'B1', treatment_template: '200000000000000000000001', parameters: {material: 'hot air', weeks: 10}});
ConditionModel.findById('700000000000000000000001').lean().exec((err, data: any) => { ConditionModel.findById('700000000000000000000001').lean().exec((err, data: any) => {
if (err) return done(err); if (err) return done(err);
should(data).have.only.keys('_id', 'sample_id', 'number', 'parameters', 'treatment_template', 'status', '__v');
should(data.sample_id.toString()).be.eql('400000000000000000000001'); should(data.sample_id.toString()).be.eql('400000000000000000000001');
should(data).have.property('number', 'B1'); should(data).have.property('number', 'B1');
should(data.treatment_template.toString()).be.eql('200000000000000000000001'); should(data.treatment_template.toString()).be.eql('200000000000000000000001');
should(data).have.property('status', 0);
should(data).have.property('parameters'); should(data).have.property('parameters');
should(data.parameters).have.property('material', 'hot air'); should(data.parameters).have.property('material', 'hot air');
should(data.parameters).have.property('weeks', 10); should(data.parameters).have.property('weeks', 10);
@ -205,7 +231,7 @@ describe('/condition', () => {
// TODO: rewrite delete methods -> set status for every database collection // TODO: rewrite delete methods -> set status for every database collection
describe('DELETE /condition/{id}', () => { describe('DELETE /condition/{id}', () => {
it('deletes the condition', done => { it('sets the status to deleted', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',
url: '/condition/700000000000000000000002', url: '/condition/700000000000000000000002',
@ -214,14 +240,21 @@ describe('/condition', () => {
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({status: 'OK'}); should(res.body).be.eql({status: 'OK'});
ConditionModel.findById('700000000000000000000002').lean().exec((err, data) => { ConditionModel.findById('700000000000000000000002').lean().exec((err, data: any) => {
if (err) return done(err); if (err) return done(err);
should(data).be.null(); should(data).have.only.keys('_id', 'sample_id', 'number', 'parameters', 'treatment_template', 'status', '__v');
should(data.sample_id.toString()).be.eql('400000000000000000000002');
should(data).have.property('number', 'B1');
should(data.treatment_template.toString()).be.eql('200000000000000000000001');
should(data).have.property('status', -1);
should(data).have.property('parameters');
should(data.parameters).have.property('material', 'copper');
should(data.parameters).have.property('weeks', 3);
done(); done();
}); });
}); });
}); });
it('rejects a deleting a condition referenced by measurements'); it('rejects a deleting a condition referenced by measurements'); // TODO
it('rejects an invalid id', done => { it('rejects an invalid id', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',
@ -315,11 +348,11 @@ describe('/condition', () => {
if (err) return done(err); if (err) return done(err);
ConditionModel.findById(res.body._id).lean().exec((err, data: any) => { ConditionModel.findById(res.body._id).lean().exec((err, data: any) => {
if (err) return done(err); if (err) return done(err);
should(data).have.only.keys('_id', 'sample_id', 'number', 'parameters', 'treatment_template', '__v'); should(data).have.only.keys('_id', 'sample_id', 'number', 'parameters', 'treatment_template', 'status', '__v');
should(data).have.property('_id');
should(data.sample_id.toString()).be.eql('400000000000000000000002'); should(data.sample_id.toString()).be.eql('400000000000000000000002');
should(data).have.property('number', 'B2'); should(data).have.property('number', 'B2');
should(data.treatment_template.toString()).be.eql('200000000000000000000001'); should(data.treatment_template.toString()).be.eql('200000000000000000000001');
should(data).have.property('status', 0);
should(data).have.property('parameters'); should(data).have.property('parameters');
should(data.parameters).have.property('material', 'hot air'); should(data.parameters).have.property('material', 'hot air');
should(data.parameters).have.property('weeks', 10); should(data.parameters).have.property('weeks', 10);

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import _ from 'lodash';
import ConditionValidate from './validate/condition'; import ConditionValidate from './validate/condition';
import ParametersValidate from './validate/parameters'; import ParametersValidate from './validate/parameters';
@ -30,7 +31,6 @@ router.put('/condition/' + IdValidate.parameter(), async (req, res, next) => {
if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return; if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return;
const {error, value: condition} = ConditionValidate.input(req.body, 'change'); const {error, value: condition} = ConditionValidate.input(req.body, 'change');
console.log(error);
if (error) return res400(error, res); if (error) return res400(error, res);
const data = await ConditionModel.findById(req.params.id).lean().exec().catch(err => {next(err);}) as any; const data = await ConditionModel.findById(req.params.id).lean().exec().catch(err => {next(err);}) as any;
@ -40,11 +40,15 @@ router.put('/condition/' + IdValidate.parameter(), async (req, res, next) => {
if (!data) { if (!data) {
res.status(404).json({status: 'Not found'}); res.status(404).json({status: 'Not found'});
} }
// add properties needed for sampleIdCheck
condition.treatment_template = data.treatment_template; condition.treatment_template = data.treatment_template;
condition.sample_id = data.sample_id; condition.sample_id = data.sample_id;
if (!await sampleIdCheck(condition, req, res, next)) return; if (!await sampleIdCheck(condition, req, res, next)) return;
if (condition.parameters) { if (condition.parameters) {
condition.parameters = Object.assign(data.parameters, condition.parameters); condition.parameters = _.assign({}, data.parameters, condition.parameters);
if (!_.isEqual(condition.parameters, data.parameters)) {
condition.status = 0;
}
} }
if (!await treatmentCheck(condition, 'change', res, next)) return; if (!await treatmentCheck(condition, 'change', res, next)) return;
@ -63,7 +67,7 @@ router.delete('/condition/' + IdValidate.parameter(), (req, res, next) => {
res.status(404).json({status: 'Not found'}); res.status(404).json({status: 'Not found'});
} }
if (!await sampleIdCheck(data, req, res, next)) return; if (!await sampleIdCheck(data, req, res, next)) return;
await ConditionModel.findByIdAndDelete(req.params.id).lean().exec(async err => { await ConditionModel.findByIdAndUpdate(req.params.id, {status: -1}).lean().exec(err => {
if (err) return next(err); if (err) return next(err);
res.json({status: 'OK'}); res.json({status: 'OK'});
}); });
@ -80,6 +84,7 @@ router.post('/condition/new', async (req, res, next) => {
if (!await numberCheck(condition, res, next)) return; if (!await numberCheck(condition, res, next)) return;
if (!await treatmentCheck(condition, 'new', res, next)) return; if (!await treatmentCheck(condition, 'new', res, next)) return;
condition.status = 0;
await new ConditionModel(condition).save((err, data) => { await new ConditionModel(condition).save((err, data) => {
if (err) return next(err); if (err) return next(err);
res.json(ConditionValidate.output(data.toObject())); res.json(ConditionValidate.output(data.toObject()));
@ -119,7 +124,6 @@ async function treatmentCheck (condition, param, res, next) {
// validate parameters // validate parameters
const {error, value: ignore} = ParametersValidate.input(condition.parameters, treatmentData.parameters, param); const {error, value: ignore} = ParametersValidate.input(condition.parameters, treatmentData.parameters, param);
console.log(error);
if (error) {res400(error, res); return false;} if (error) {res400(error, res); return false;}
return true; return true;
} }

View File

@ -2,6 +2,8 @@ import should from 'should/as-function';
import MaterialModel from '../models/material'; import MaterialModel from '../models/material';
import TestHelper from "../test/helper"; import TestHelper from "../test/helper";
// TODO: status // TODO: status
// TODO: numbers with color only (no number)
// TODO: deal with numbers with leading zeros
describe('/material', () => { describe('/material', () => {
let server; let server;
@ -19,7 +21,8 @@ describe('/material', () => {
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
const json = require('../test/db.json'); const json = require('../test/db.json');
should(res.body).have.lengthOf(json.collections.materials.length); console.log(res.body);
should(res.body).have.lengthOf(json.collections.materials.filter(e => e.status === 10).length);
should(res.body).matchEach(material => { should(res.body).matchEach(material => {
should(material).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers'); should(material).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers');
should(material).have.property('_id').be.type('string'); should(material).have.property('_id').be.type('string');
@ -47,7 +50,7 @@ describe('/material', () => {
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
const json = require('../test/db.json'); const json = require('../test/db.json');
should(res.body).have.lengthOf(json.collections.materials.length); should(res.body).have.lengthOf(json.collections.materials.filter(e => e.status === 10).length);
should(res.body).matchEach(material => { should(res.body).matchEach(material => {
should(material).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers'); should(material).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers');
should(material).have.property('_id').be.type('string'); should(material).have.property('_id').be.type('string');
@ -136,8 +139,32 @@ describe('/material', () => {
url: '/material/100000000000000000000001', url: '/material/100000000000000000000001',
auth: {basic: 'janedoe'}, auth: {basic: 'janedoe'},
httpStatus: 200, httpStatus: 200,
req: {name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}]}, req: {name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]}
res: {_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}]} }).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]});
MaterialModel.findById('100000000000000000000001').lean().exec((err, data) => {
if (err) return done(err);
should(data).have.property('status', 10);
done();
});
});
});
it('keeps only one unchanged property', done => {
TestHelper.request(server, done, {
method: 'put',
url: '/material/100000000000000000000001',
auth: {basic: 'janedoe'},
httpStatus: 200,
req: {name: 'Stanyl TW 200 F8'}
}).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]});
MaterialModel.findById('100000000000000000000001').lean().exec((err, data) => {
if (err) return done(err);
should(data).have.property('status', 10);
done();
});
}); });
}); });
it('changes the given properties', done => { it('changes the given properties', done => {
@ -155,8 +182,7 @@ describe('/material', () => {
if (err) return done(err); if (err) return done(err);
data._id = data._id.toString(); data._id = data._id.toString();
data.numbers = data.numbers.map(e => {return {color: e.color, number: e.number}}); data.numbers = data.numbers.map(e => {return {color: e.color, number: e.number}});
should(data).be.eql({_id: '100000000000000000000001', name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: '0', glass_fiber: '35', carbon_fiber: '0', numbers: [{color: 'black', number: 5514212901}, {color: 'signalviolet', number: 5514612901}], __v: 0} should(data).be.eql({_id: '100000000000000000000001', name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: '0', glass_fiber: '35', carbon_fiber: '0', numbers: [{color: 'black', number: 5514212901}, {color: 'signalviolet', number: 5514612901}], status: 0, __v: 0});
);
done(); done();
}); });
}); });
@ -268,7 +294,7 @@ describe('/material', () => {
}); });
describe('DELETE /material/{id}', () => { describe('DELETE /material/{id}', () => {
it('deletes the material', done => { it('sets the status to deleted', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',
url: '/material/100000000000000000000002', url: '/material/100000000000000000000002',
@ -277,9 +303,12 @@ describe('/material', () => {
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({status: 'OK'}); should(res.body).be.eql({status: 'OK'});
MaterialModel.findById('100000000000000000000002').lean().exec((err, data) => { MaterialModel.findById('100000000000000000000002').lean().exec((err, data: any) => {
if (err) return done(err); if (err) return done(err);
should(data).be.null(); data._id = data._id.toString();
data.numbers = data.numbers.map(e => {return {color: e.color, number: e.number}});
should(data).be.eql({_id: '100000000000000000000002', name: 'Ultramid T KR 4355 G7', supplier: 'BASF', group: 'PA6/6T', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: 5514212901}, {color: 'signalviolet', number: 5514612901}], status: -1, __v: 0}
);
done(); done();
}); });
}); });
@ -372,7 +401,7 @@ describe('/material', () => {
MaterialModel.find({name: 'Crastin CE 2510'}).lean().exec((err, data: any) => { MaterialModel.find({name: 'Crastin CE 2510'}).lean().exec((err, data: any) => {
if (err) return done (err); if (err) return done (err);
should(data).have.lengthOf(1); should(data).have.lengthOf(1);
should(data[0]).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers', '__v'); should(data[0]).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers', 'status', '__v');
should(data[0]).have.property('_id'); should(data[0]).have.property('_id');
should(data[0]).have.property('name', 'Crastin CE 2510'); should(data[0]).have.property('name', 'Crastin CE 2510');
should(data[0]).have.property('supplier', 'Du Pont'); should(data[0]).have.property('supplier', 'Du Pont');
@ -380,6 +409,7 @@ describe('/material', () => {
should(data[0]).have.property('mineral', '0'); should(data[0]).have.property('mineral', '0');
should(data[0]).have.property('glass_fiber', '30'); should(data[0]).have.property('glass_fiber', '30');
should(data[0]).have.property('carbon_fiber', '0'); should(data[0]).have.property('carbon_fiber', '0');
should(data[0]).have.property('status', 0);
should(data[0].numbers).have.lengthOf(0); should(data[0].numbers).have.lengthOf(0);
done(); done();
}); });

View File

@ -8,13 +8,14 @@ import IdValidate from './validate/id';
import res400 from './validate/res400'; import res400 from './validate/res400';
import mongoose from 'mongoose'; import mongoose from 'mongoose';
// TODO: remove f() for await
const router = express.Router(); const router = express.Router();
router.get('/materials', (req, res, next) => { router.get('/materials', (req, res, next) => {
if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return; if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return;
MaterialModel.find({}).lean().exec((err, data) => { MaterialModel.find({status: 10}).lean().exec((err, data) => {
if (err) return next(err); if (err) return next(err);
res.json(_.compact(data.map(e => MaterialValidate.output(e)))); // validate all and filter null values from validation errors res.json(_.compact(data.map(e => MaterialValidate.output(e)))); // validate all and filter null values from validation errors
}); });
@ -40,33 +41,24 @@ router.put('/material/' + IdValidate.parameter(), (req, res, next) => {
const {error, value: material} = MaterialValidate.input(req.body, 'change'); const {error, value: material} = MaterialValidate.input(req.body, 'change');
if (error) return res400(error, res); if (error) return res400(error, res);
if (material.hasOwnProperty('name')) { MaterialModel.findById(req.params.id).lean().exec(async (err, materialData: any) => {
MaterialModel.find({name: material.name}).lean().exec((err, data) => { if (!materialData) {
if (err) return next(err); return res.status(404).json({status: 'Not found'});
if (data.length > 0 && data[0]._id != req.params.id) {
res.status(400).json({status: 'Material name already taken'});
return;
} }
else { if (material.hasOwnProperty('name') && material.name !== materialData.name) {
f(); if (!await nameCheck(material, res, next)) return;
}
});
}
else {
f();
} }
function f() { // to resolve async // check for changes
MaterialModel.findByIdAndUpdate(req.params.id, material, {new: true}).lean().exec((err, data) => { if (!_.isEqual(_.pick(IdValidate.stringify(materialData), _.keys(material)), material)) {
material.status = 0;
}
await MaterialModel.findByIdAndUpdate(req.params.id, material, {new: true}).lean().exec((err, data) => {
if (err) return next(err); if (err) return next(err);
if (data) {
res.json(MaterialValidate.output(data)); res.json(MaterialValidate.output(data));
}
else {
res.status(404).json({status: 'Not found'});
}
}); });
} });
}); });
router.delete('/material/' + IdValidate.parameter(), (req, res, next) => { router.delete('/material/' + IdValidate.parameter(), (req, res, next) => {
@ -78,7 +70,7 @@ router.delete('/material/' + IdValidate.parameter(), (req, res, next) => {
if (data.length) { if (data.length) {
return res.status(400).json({status: 'Material still in use'}); return res.status(400).json({status: 'Material still in use'});
} }
MaterialModel.findByIdAndDelete(req.params.id).lean().exec((err, data) => { MaterialModel.findByIdAndUpdate(req.params.id, {status: -1}).lean().exec((err, data) => {
if (err) return next(err); if (err) return next(err);
if (data) { if (data) {
res.json({status: 'OK'}); res.json({status: 'OK'});
@ -90,26 +82,34 @@ router.delete('/material/' + IdValidate.parameter(), (req, res, next) => {
}); });
}); });
router.post('/material/new', (req, res, next) => { router.post('/material/new', async (req, res, next) => {
if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return; if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return;
// validate input // validate input
const {error, value: material} = MaterialValidate.input(req.body, 'new'); const {error, value: material} = MaterialValidate.input(req.body, 'new');
if (error) return res400(error, res); if (error) return res400(error, res);
MaterialModel.find({name: material.name}).lean().exec((err, data) => { if (!await nameCheck(material, res, next)) return;
if (err) return next(err);
if (data.length > 0) {
res.status(400).json({status: 'Material name already taken'});
return;
}
new MaterialModel(material).save((err, data) => { material.status = 0;
await new MaterialModel(material).save((err, data) => {
if (err) return next(err); if (err) return next(err);
res.json(MaterialValidate.output(data.toObject())); res.json(MaterialValidate.output(data.toObject()));
}); });
}); });
});
module.exports = router; module.exports = router;
async function nameCheck (material, res, next) { // check if name was already taken
const materialData = await MaterialModel.findOne({name: material.name}).lean().exec().catch(err => {next(err); return false;}) as any;
if (materialData instanceof Error) {
return false;
}
if (materialData) { // could not find material_id
res.status(400).json({status: 'Material name already taken'});
return false;
}
return true;
}

View File

@ -74,6 +74,24 @@ describe('/measurement', () => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({_id: '800000000000000000000001', condition_id: '700000000000000000000001', values: {dpt: [[3997.12558,98.00555],[3995.08519,98.03253],[3993.04480,98.02657]]}, measurement_template: '300000000000000000000001'}); should(res.body).be.eql({_id: '800000000000000000000001', condition_id: '700000000000000000000001', values: {dpt: [[3997.12558,98.00555],[3995.08519,98.03253],[3993.04480,98.02657]]}, measurement_template: '300000000000000000000001'});
MeasurementModel.findById('800000000000000000000001').lean().exec((err, data: any) => { MeasurementModel.findById('800000000000000000000001').lean().exec((err, data: any) => {
if (err) return done(err);
should(data).have.property('status', 10);
done();
});
});
});
it('keeps only one unchanged value', done => {
TestHelper.request(server, done, {
method: 'put',
url: '/measurement/800000000000000000000002',
auth: {basic: 'janedoe'},
httpStatus: 200,
req: {values: {'weight %': 0.5}}
}).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '800000000000000000000002', condition_id: '700000000000000000000002', values: {'weight %': 0.5, 'standard deviation': 0.2}, measurement_template: '300000000000000000000002'});
MeasurementModel.findById('800000000000000000000002').lean().exec((err, data: any) => {
if (err) return done(err);
should(data).have.property('status', 10); should(data).have.property('status', 10);
done(); done();
}); });

View File

@ -41,12 +41,12 @@ router.put('/measurement/' + IdValidate.parameter(), async (req, res, next) => {
// add properties needed for conditionIdCheck // add properties needed for conditionIdCheck
measurement.measurement_template = data.measurement_template; measurement.measurement_template = data.measurement_template;
measurement.condition_id = data.condition_id; measurement.condition_id = data.condition_id;
if (measurement.hasOwnProperty('values') && !_.isEqual(measurement.values, data.values)) {
measurement.status = 0;
}
if (!await conditionIdCheck(measurement, req, res, next)) return; if (!await conditionIdCheck(measurement, req, res, next)) return;
if (measurement.values) { if (measurement.values) {
measurement.values = Object.assign(data.values, measurement.values); measurement.values = _.assign({}, data.values, measurement.values);
if (!_.isEqual(measurement.values, data.values)) {
measurement.status = 0;
}
} }
if (!await templateCheck(measurement, 'change', res, next)) return; if (!await templateCheck(measurement, 'change', res, next)) return;
await MeasurementModel.findByIdAndUpdate(req.params.id, measurement, {new: true}).lean().exec((err, data) => { await MeasurementModel.findByIdAndUpdate(req.params.id, measurement, {new: true}).lean().exec((err, data) => {
@ -64,7 +64,7 @@ router.delete('/measurement/' + IdValidate.parameter(), (req, res, next) => {
res.status(404).json({status: 'Not found'}); res.status(404).json({status: 'Not found'});
} }
if (!await conditionIdCheck(data, req, res, next)) return; if (!await conditionIdCheck(data, req, res, next)) return;
await MeasurementModel.findByIdAndUpdate(req.params.id, {status: -1}).lean().exec(async err => { await MeasurementModel.findByIdAndUpdate(req.params.id, {status: -1}).lean().exec(err => {
if (err) return next(err); if (err) return next(err);
res.json({status: 'OK'}); res.json({status: 'OK'});
}); });

View File

@ -5,7 +5,6 @@ import NoteFieldModel from '../models/note_field';
import TestHelper from "../test/helper"; import TestHelper from "../test/helper";
// TODO: generate sample number // TODO: generate sample number
// TODO: think again which parameters are required at POST // TODO: think again which parameters are required at POST
// TODO: status
describe('/sample', () => { describe('/sample', () => {
let server; let server;
@ -23,7 +22,7 @@ describe('/sample', () => {
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
const json = require('../test/db.json'); const json = require('../test/db.json');
should(res.body).have.lengthOf(json.collections.samples.length); should(res.body).have.lengthOf(json.collections.samples.filter(e => e.status === 10).length);
should(res.body).matchEach(material => { should(res.body).matchEach(material => {
should(material).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'material_id', 'note_id', 'user_id'); should(material).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'material_id', 'note_id', 'user_id');
should(material).have.property('_id').be.type('string'); should(material).have.property('_id').be.type('string');
@ -47,7 +46,7 @@ describe('/sample', () => {
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
const json = require('../test/db.json'); const json = require('../test/db.json');
should(res.body).have.lengthOf(json.collections.samples.length); should(res.body).have.lengthOf(json.collections.samples.filter(e => e.status === 10).length);
should(res.body).matchEach(material => { should(res.body).matchEach(material => {
should(material).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'material_id', 'note_id', 'user_id'); should(material).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'material_id', 'note_id', 'user_id');
should(material).have.property('_id').be.type('string'); should(material).have.property('_id').be.type('string');
@ -88,8 +87,41 @@ describe('/sample', () => {
url: '/sample/400000000000000000000001', url: '/sample/400000000000000000000001',
auth: {basic: 'janedoe'}, auth: {basic: 'janedoe'},
httpStatus: 200, httpStatus: 200,
req: {number: '1', type: 'granulate', color: 'black', batch: '', material_id: '100000000000000000000004', notes: {}}, req: {number: '1', type: 'granulate', color: 'black', batch: '', material_id: '100000000000000000000004', notes: {}}
res: {_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'} }).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'});
SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => {
if (err) return done (err);
should(data).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'material_id', 'note_id', 'user_id', 'status', '__v');
should(data).have.property('_id');
should(data).have.property('number', '1');
should(data).have.property('color', 'black');
should(data).have.property('type', 'granulate');
should(data).have.property('batch', '');
should(data.material_id.toString()).be.eql('100000000000000000000004');
should(data.user_id.toString()).be.eql('000000000000000000000002');
should(data).have.property('status', 10);
should(data).have.property('note_id', null);
done();
});
});
});
it('keeps only one unchanged parameter', done => {
TestHelper.request(server, done, {
method: 'put',
url: '/sample/400000000000000000000001',
auth: {basic: 'janedoe'},
httpStatus: 200,
req: {type: 'granulate'}
}).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'});
SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => {
if (err) return done (err);
should(data).have.property('status', 10);
done();
});
}); });
}); });
it('changes the given properties', done => { it('changes the given properties', done => {
@ -103,15 +135,15 @@ describe('/sample', () => {
if (err) return done (err); if (err) return done (err);
SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => { SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => {
if (err) return done (err); if (err) return done (err);
should(data).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'validated', 'material_id', 'note_id', 'user_id', '__v'); should(data).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'material_id', 'note_id', 'user_id', 'status', '__v');
should(data).have.property('_id'); should(data).have.property('_id');
should(data).have.property('number', '10'); should(data).have.property('number', '10');
should(data).have.property('color', 'signalviolet'); should(data).have.property('color', 'signalviolet');
should(data).have.property('type', 'part'); should(data).have.property('type', 'part');
should(data).have.property('batch', '114531'); should(data).have.property('batch', '114531');
should(data).have.property('validated').be.type('boolean');
should(data.material_id.toString()).be.eql('100000000000000000000002'); should(data.material_id.toString()).be.eql('100000000000000000000002');
should(data.user_id.toString()).be.eql('000000000000000000000002'); should(data.user_id.toString()).be.eql('000000000000000000000002');
should(data).have.property('status', 0);
should(data).have.property('note_id'); should(data).have.property('note_id');
NoteModel.findById(data.note_id).lean().exec((err, data: any) => { NoteModel.findById(data.note_id).lean().exec((err, data: any) => {
if (err) return done (err); if (err) return done (err);
@ -123,7 +155,7 @@ describe('/sample', () => {
should(data.sample_references[0]).have.property('relation', 'part to this sample'); should(data.sample_references[0]).have.property('relation', 'part to this sample');
done(); done();
}); });
}) });
}); });
}); });
it('adjusts the note_fields correctly', done => { it('adjusts the note_fields correctly', done => {
@ -315,7 +347,7 @@ describe('/sample', () => {
}); });
describe('DELETE /sample/{id}', () => { describe('DELETE /sample/{id}', () => {
it('deletes the sample', done => { it('sets the status to deleted', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',
url: '/sample/400000000000000000000001', url: '/sample/400000000000000000000001',
@ -324,14 +356,23 @@ describe('/sample', () => {
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({status: 'OK'}); should(res.body).be.eql({status: 'OK'});
SampleModel.findById('400000000000000000000001').lean().exec((err, data) => { SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => {
if (err) return done(err); if (err) return done(err);
should(data).be.null(); should(data).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'material_id', 'note_id', 'user_id', 'status', '__v');
should(data).have.property('_id');
should(data).have.property('number', '1');
should(data).have.property('color', 'black');
should(data).have.property('type', 'granulate');
should(data).have.property('batch', '');
should(data.material_id.toString()).be.eql('100000000000000000000004');
should(data.user_id.toString()).be.eql('000000000000000000000002');
should(data).have.property('status', -1);
should(data).have.property('note_id', null);
done(); done();
}); });
}); });
}); });
it('deletes the notes of the sample', done => { it('keeps the notes of the sample', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',
url: '/sample/400000000000000000000002', url: '/sample/400000000000000000000002',
@ -342,7 +383,9 @@ describe('/sample', () => {
should(res.body).be.eql({status: 'OK'}); should(res.body).be.eql({status: 'OK'});
NoteModel.findById('500000000000000000000001').lean().exec((err, data) => { NoteModel.findById('500000000000000000000001').lean().exec((err, data) => {
if (err) return done(err); if (err) return done(err);
should(data).be.null(); should(data).have.only.keys('_id', 'comment', 'sample_references', '__v');
should(data).have.property('comment', 'Stoff gesperrt');
should(data).have.property('sample_references').with.lengthOf(0);
done(); done();
}); });
}); });
@ -367,7 +410,7 @@ describe('/sample', () => {
}); });
}); });
}); });
it('resets references to this sample', done => { it('keeps references to this sample', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',
url: '/sample/400000000000000000000003', url: '/sample/400000000000000000000003',
@ -377,10 +420,12 @@ describe('/sample', () => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({status: 'OK'}); should(res.body).be.eql({status: 'OK'});
setTimeout(() => { // background action takes some time before we can check setTimeout(() => { // background action takes some time before we can check
NoteModel.findById('500000000000000000000003').lean().exec((err, data) => { NoteModel.findById('500000000000000000000003').lean().exec((err, data: any) => {
if (err) return done(err); if (err) return done(err);
console.log(data); console.log(data);
should(data).have.property('sample_references').with.lengthOf(0); should(data).have.property('sample_references').with.lengthOf(1);
should(data.sample_references[0].id.toString()).be.eql('400000000000000000000003');
should(data.sample_references[0]).have.property('relation', 'part to sample');
done(); done();
}); });
}, 100); }, 100);
@ -398,7 +443,7 @@ describe('/sample', () => {
should(res.body).be.eql({status: 'OK'}); should(res.body).be.eql({status: 'OK'});
SampleModel.findById('400000000000000000000001').lean().exec((err, data) => { SampleModel.findById('400000000000000000000001').lean().exec((err, data) => {
if (err) return done(err); if (err) return done(err);
should(data).be.null(); should(data).have.property('status', -1);
done(); done();
}); });
}); });
@ -486,7 +531,7 @@ describe('/sample', () => {
SampleModel.find({number: 'Rng172'}).lean().exec((err, data: any) => { SampleModel.find({number: 'Rng172'}).lean().exec((err, data: any) => {
if (err) return done (err); if (err) return done (err);
should(data).have.lengthOf(1); should(data).have.lengthOf(1);
should(data[0]).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'material_id', 'note_id', 'user_id', '__v'); should(data[0]).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'material_id', 'note_id', 'user_id', 'status', '__v');
should(data[0]).have.property('_id'); should(data[0]).have.property('_id');
should(data[0]).have.property('number', 'Rng172'); should(data[0]).have.property('number', 'Rng172');
should(data[0]).have.property('color', 'black'); should(data[0]).have.property('color', 'black');
@ -494,6 +539,7 @@ describe('/sample', () => {
should(data[0]).have.property('batch', '1560237365'); should(data[0]).have.property('batch', '1560237365');
should(data[0].material_id.toString()).be.eql('100000000000000000000001'); should(data[0].material_id.toString()).be.eql('100000000000000000000001');
should(data[0].user_id.toString()).be.eql('000000000000000000000002'); should(data[0].user_id.toString()).be.eql('000000000000000000000002');
should(data[0]).have.property('status', 0);
should(data[0]).have.property('note_id'); should(data[0]).have.property('note_id');
NoteModel.findById(data[0].note_id).lean().exec((err, data: any) => { NoteModel.findById(data[0].note_id).lean().exec((err, data: any) => {
if (err) return done (err); if (err) return done (err);

View File

@ -16,7 +16,7 @@ const router = express.Router();
router.get('/samples', (req, res, next) => { router.get('/samples', (req, res, next) => {
if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return; if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return;
SampleModel.find({}).lean().exec((err, data) => { SampleModel.find({status: 10}).lean().exec((err, data) => {
if (err) return next(err); if (err) return next(err);
res.json(_.compact(data.map(e => SampleValidate.output(e)))); // validate all and filter null values from validation errors res.json(_.compact(data.map(e => SampleValidate.output(e)))); // validate all and filter null values from validation errors
}) })
@ -66,6 +66,11 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => {
delete sample.notes; delete sample.notes;
sample.note_id = data._id; sample.note_id = data._id;
} }
// check for changes
if (!_.isEqual(_.pick(IdValidate.stringify(sampleData), _.keys(sample)), _.omit(sample, ['notes']))) {
sample.status = 0;
}
SampleModel.findByIdAndUpdate(req.params.id, sample, {new: true}).lean().exec((err, data) => { SampleModel.findByIdAndUpdate(req.params.id, sample, {new: true}).lean().exec((err, data) => {
if (err) return next(err); if (err) return next(err);
res.json(SampleValidate.output(data)); res.json(SampleValidate.output(data));
@ -85,22 +90,15 @@ router.delete('/sample/' + IdValidate.parameter(), (req, res, next) => {
// only maintain and admin are allowed to edit other user's data // only maintain and admin are allowed to edit other user's data
if (sampleData.user_id.toString() !== req.authDetails.id && !req.auth(res, ['maintain', 'admin'], 'basic')) return; if (sampleData.user_id.toString() !== req.authDetails.id && !req.auth(res, ['maintain', 'admin'], 'basic')) return;
SampleModel.findByIdAndDelete(req.params.id).lean().exec(err => { // delete sample SampleModel.findByIdAndUpdate(req.params.id, {status: -1}).lean().exec(err => { // set sample status
if (err) return next(err); if (err) return next(err);
if (sampleData.note_id !== null) { if (sampleData.note_id !== null) {
NoteModel.findByIdAndDelete(sampleData.note_id).lean().exec((err, data: any) => { // delete notes NoteModel.findById(sampleData.note_id).lean().exec((err, data: any) => { // find notes to update note_fields
if (err) return next(err); if (err) return next(err);
console.log(data);
if (data.hasOwnProperty('custom_fields')) { // update note_fields if (data.hasOwnProperty('custom_fields')) { // update note_fields
customFieldsChange(Object.keys(data.custom_fields), -1); customFieldsChange(Object.keys(data.custom_fields), -1);
} }
res.json({status: 'OK'}); res.json({status: 'OK'});
NoteModel.updateMany({'sample_references.id': req.params.id}, {$unset: {'sample_references.$': null}}).lean().exec(err => { // remove sample_references
if (err) console.error(err);
NoteModel.collection.updateMany({sample_references: null}, {$pull: {sample_references: null}}, err => { // only works with native MongoDB driver somehow
if (err) console.error(err);
});
});
}); });
} }
else { else {
@ -124,6 +122,7 @@ router.post('/sample/new', async (req, res, next) => {
customFieldsChange(Object.keys(sample.notes.custom_fields), 1); customFieldsChange(Object.keys(sample.notes.custom_fields), 1);
} }
sample.status = 0;
new NoteModel(sample.notes).save((err, data) => { new NoteModel(sample.notes).save((err, data) => {
if (err) return next(err); if (err) return next(err);
delete sample.notes; delete sample.notes;

View File

@ -6,6 +6,7 @@ import TemplateTreatmentModel from '../models/treatment_template';
import TemplateMeasurementModel from '../models/measurement_template'; import TemplateMeasurementModel from '../models/measurement_template';
import res400 from './validate/res400'; import res400 from './validate/res400';
// TODO: remove f() for await
const router = express.Router(); const router = express.Router();

View File

@ -7,10 +7,10 @@
"type": "granulate", "type": "granulate",
"color": "black", "color": "black",
"batch": "", "batch": "",
"validated": true,
"material_id": {"$oid":"100000000000000000000004"}, "material_id": {"$oid":"100000000000000000000004"},
"note_id": null, "note_id": null,
"user_id": {"$oid":"000000000000000000000002"}, "user_id": {"$oid":"000000000000000000000002"},
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -19,10 +19,10 @@
"type": "granulate", "type": "granulate",
"color": "natural", "color": "natural",
"batch": "1560237365", "batch": "1560237365",
"validated": true,
"material_id": {"$oid":"100000000000000000000001"}, "material_id": {"$oid":"100000000000000000000001"},
"note_id": {"$oid":"500000000000000000000001"}, "note_id": {"$oid":"500000000000000000000001"},
"user_id": {"$oid":"000000000000000000000002"}, "user_id": {"$oid":"000000000000000000000002"},
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -31,10 +31,10 @@
"type": "part", "type": "part",
"color": "black", "color": "black",
"batch": "1704-005", "batch": "1704-005",
"validated": false,
"material_id": {"$oid":"100000000000000000000005"}, "material_id": {"$oid":"100000000000000000000005"},
"note_id": {"$oid":"500000000000000000000002"}, "note_id": {"$oid":"500000000000000000000002"},
"user_id": {"$oid":"000000000000000000000003"}, "user_id": {"$oid":"000000000000000000000003"},
"status": 0,
"__v": 0 "__v": 0
}, },
{ {
@ -43,10 +43,22 @@
"type": "granulate", "type": "granulate",
"color": "black", "color": "black",
"batch": "1653000308", "batch": "1653000308",
"validated": false,
"material_id": {"$oid":"100000000000000000000005"}, "material_id": {"$oid":"100000000000000000000005"},
"note_id": {"$oid":"500000000000000000000003"}, "note_id": {"$oid":"500000000000000000000003"},
"user_id": {"$oid":"000000000000000000000003"}, "user_id": {"$oid":"000000000000000000000003"},
"status": 0,
"__v": 0
},
{
"_id": {"$oid":"400000000000000000000005"},
"number": "33",
"type": "granulate",
"color": "black",
"batch": "1653000308",
"material_id": {"$oid":"100000000000000000000005"},
"note_id": {"$oid":"500000000000000000000003"},
"user_id": {"$oid":"000000000000000000000003"},
"status": -1,
"__v": 0 "__v": 0
} }
], ],
@ -116,6 +128,7 @@
"number": 5514263422 "number": 5514263422
} }
], ],
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -136,6 +149,7 @@
"number": 5514612901 "number": 5514612901
} }
], ],
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -148,6 +162,7 @@
"carbon_fiber": 0, "carbon_fiber": 0,
"numbers": [ "numbers": [
], ],
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -164,6 +179,7 @@
"number": 5513933405 "number": 5513933405
} }
], ],
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -180,6 +196,24 @@
"number": 5514262406 "number": 5514262406
} }
], ],
"status": 10,
"__v": 0
},
{
"_id": {"$oid":"100000000000000000000006"},
"name": "PK-HM natural (4773)",
"supplier": "Akro-Plastic",
"group": "PK",
"mineral": 0,
"glass_fiber": 0,
"carbon_fiber": 0,
"numbers": [
{
"color": "natural",
"number": 10000000
}
],
"status": -1,
"__v": 0 "__v": 0
} }
], ],
@ -193,6 +227,7 @@
"weeks": 3 "weeks": 3
}, },
"treatment_template": {"$oid":"200000000000000000000001"}, "treatment_template": {"$oid":"200000000000000000000001"},
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -204,6 +239,7 @@
"weeks": 3 "weeks": 3
}, },
"treatment_template": {"$oid":"200000000000000000000001"}, "treatment_template": {"$oid":"200000000000000000000001"},
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -215,6 +251,7 @@
"weeks": 3 "weeks": 3
}, },
"treatment_template": {"$oid":"200000000000000000000001"}, "treatment_template": {"$oid":"200000000000000000000001"},
"status": 10,
"__v": 0 "__v": 0
}, },
{ {
@ -226,6 +263,7 @@
"weeks": 5 "weeks": 5
}, },
"treatment_template": {"$oid":"200000000000000000000001"}, "treatment_template": {"$oid":"200000000000000000000001"},
"status": 10,
"__v": 0 "__v": 0
} }
], ],