adjusted material
This commit is contained in:
parent
478660573d
commit
806b77eecf
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
@ -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();
|
||||||
});
|
});
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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();
|
||||||
|
|
||||||
|
@ -128,6 +128,7 @@
|
|||||||
"number": 5514263422
|
"number": 5514263422
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"status": 10,
|
||||||
"__v": 0
|
"__v": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -148,6 +149,7 @@
|
|||||||
"number": 5514612901
|
"number": 5514612901
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"status": 10,
|
||||||
"__v": 0
|
"__v": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -160,6 +162,7 @@
|
|||||||
"carbon_fiber": 0,
|
"carbon_fiber": 0,
|
||||||
"numbers": [
|
"numbers": [
|
||||||
],
|
],
|
||||||
|
"status": 10,
|
||||||
"__v": 0
|
"__v": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -176,6 +179,7 @@
|
|||||||
"number": 5513933405
|
"number": 5513933405
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"status": 10,
|
||||||
"__v": 0
|
"__v": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -192,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
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user