separated groups and suppliers for material PUT and POST
This commit is contained in:
		@@ -1,10 +1,12 @@
 | 
			
		||||
import should from 'should/as-function';
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
import MaterialModel from '../models/material';
 | 
			
		||||
import MaterialGroupModel from '../models/material_groups';
 | 
			
		||||
import MaterialSupplierModel from '../models/material_suppliers';
 | 
			
		||||
import TestHelper from "../test/helper";
 | 
			
		||||
import globals from '../globals';
 | 
			
		||||
 | 
			
		||||
// TODO: separate supplier/ material name into own collections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
describe('/material', () => {
 | 
			
		||||
  let server;
 | 
			
		||||
@@ -267,7 +269,17 @@ describe('/material', () => {
 | 
			
		||||
        MaterialModel.findById('100000000000000000000001').lean().exec((err, data) => {
 | 
			
		||||
          if (err) return done(err);
 | 
			
		||||
          should(data).have.property('status',globals.status.validated);
 | 
			
		||||
          done();
 | 
			
		||||
          MaterialGroupModel.find({name: 'PA46'}).lean().exec((err, data) => {
 | 
			
		||||
            if (err) return done(err);
 | 
			
		||||
            should(data).have.lengthOf(1);
 | 
			
		||||
            should(data[0]._id.toString()).be.eql('900000000000000000000001');
 | 
			
		||||
            MaterialSupplierModel.find({name: 'DSM'}).lean().exec((err, data) => {
 | 
			
		||||
              if (err) return done(err);
 | 
			
		||||
              should(data).have.lengthOf(1);
 | 
			
		||||
              should(data[0]._id.toString()).be.eql('110000000000000000000001');
 | 
			
		||||
              done();
 | 
			
		||||
            });
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -302,9 +314,21 @@ describe('/material', () => {
 | 
			
		||||
        MaterialModel.findById('100000000000000000000001').lean().exec((err, data:any) => {
 | 
			
		||||
          if (err) return done(err);
 | 
			
		||||
          data._id = data._id.toString();
 | 
			
		||||
          data.group_id = data.group_id.toString();
 | 
			
		||||
          data.supplier_id = data.supplier_id.toString();
 | 
			
		||||
          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'}], status: 0, __v: 0});
 | 
			
		||||
          done();
 | 
			
		||||
          should(data).be.eql({_id: '100000000000000000000001', name: 'UltramidTKR4355G7_2', supplier_id: '110000000000000000000002', group_id: '900000000000000000000002', mineral: '0', glass_fiber: '35', carbon_fiber: '0', numbers: [{color: 'black', number: '5514212901'}, {color: 'signalviolet', number: '5514612901'}], status: 0, __v: 0});
 | 
			
		||||
          MaterialGroupModel.find({name: 'PA6/6T'}).lean().exec((err, data) => {
 | 
			
		||||
            if (err) return done(err);
 | 
			
		||||
            should(data).have.lengthOf(1);
 | 
			
		||||
            should(data[0]._id.toString()).be.eql('900000000000000000000002');
 | 
			
		||||
            MaterialSupplierModel.find({name: 'BASF'}).lean().exec((err, data) => {
 | 
			
		||||
              if (err) return done(err);
 | 
			
		||||
              should(data).have.lengthOf(1);
 | 
			
		||||
              should(data[0]._id.toString()).be.eql('110000000000000000000002');
 | 
			
		||||
              done();
 | 
			
		||||
            });
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -436,8 +460,10 @@ describe('/material', () => {
 | 
			
		||||
        MaterialModel.findById('100000000000000000000002').lean().exec((err, data: any) => {
 | 
			
		||||
          if (err) return done(err);
 | 
			
		||||
          data._id = data._id.toString();
 | 
			
		||||
          data.group_id = data.group_id.toString();
 | 
			
		||||
          data.supplier_id = data.supplier_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}
 | 
			
		||||
          should(data).be.eql({_id: '100000000000000000000002', name: 'Ultramid T KR 4355 G7', supplier_id: '110000000000000000000002', group_id: '900000000000000000000002', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: '5514212901'}, {color: 'signalviolet', number: '5514612901'}], status: -1, __v: 0}
 | 
			
		||||
          );
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
@@ -583,20 +609,25 @@ describe('/material', () => {
 | 
			
		||||
        req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: []}
 | 
			
		||||
      }).end(err => {
 | 
			
		||||
        if (err) return done (err);
 | 
			
		||||
        MaterialModel.find({name: 'Crastin CE 2510'}).lean().exec((err, data: any) => {
 | 
			
		||||
        MaterialModel.find({name: 'Crastin CE 2510'}).lean().exec((err, materialData: any) => {
 | 
			
		||||
          if (err) return done (err);
 | 
			
		||||
          should(data).have.lengthOf(1);
 | 
			
		||||
          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('name', 'Crastin CE 2510');
 | 
			
		||||
          should(data[0]).have.property('supplier', 'Du Pont');
 | 
			
		||||
          should(data[0]).have.property('group', 'PBT');
 | 
			
		||||
          should(data[0]).have.property('mineral', '0');
 | 
			
		||||
          should(data[0]).have.property('glass_fiber', '30');
 | 
			
		||||
          should(data[0]).have.property('carbon_fiber', '0');
 | 
			
		||||
          should(data[0]).have.property('status',globals.status.new);
 | 
			
		||||
          should(data[0].numbers).have.lengthOf(0);
 | 
			
		||||
          done();
 | 
			
		||||
          should(materialData).have.lengthOf(1);
 | 
			
		||||
          should(materialData[0]).have.only.keys('_id', 'name', 'supplier_id', 'group_id', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers', 'status', '__v');
 | 
			
		||||
          should(materialData[0]).have.property('name', 'Crastin CE 2510');
 | 
			
		||||
          should(materialData[0]).have.property('mineral', '0');
 | 
			
		||||
          should(materialData[0]).have.property('glass_fiber', '30');
 | 
			
		||||
          should(materialData[0]).have.property('carbon_fiber', '0');
 | 
			
		||||
          should(materialData[0]).have.property('status',globals.status.new);
 | 
			
		||||
          should(materialData[0].numbers).have.lengthOf(0);
 | 
			
		||||
          MaterialGroupModel.findById(materialData[0].group_id).lean().exec((err, data) => {
 | 
			
		||||
            if (err) return done(err);
 | 
			
		||||
            should(data).have.property('name', 'PBT')
 | 
			
		||||
            MaterialSupplierModel.findById(materialData[0].supplier_id).lean().exec((err, data) => {
 | 
			
		||||
              if (err) return done(err);
 | 
			
		||||
              should(data).have.property('name', 'Du Pont');
 | 
			
		||||
              done();
 | 
			
		||||
            });
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -625,11 +656,9 @@ describe('/material', () => {
 | 
			
		||||
        MaterialModel.find({name: 'Crastin CE 2510'}).lean().exec((err, data: any) => {
 | 
			
		||||
          if (err) return done (err);
 | 
			
		||||
          should(data).have.lengthOf(1);
 | 
			
		||||
          should(data[0]).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers', 'status', '__v');
 | 
			
		||||
          should(data[0]).have.only.keys('_id', 'name', 'supplier_id', 'group_id', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers', 'status', '__v');
 | 
			
		||||
          should(data[0]).have.property('_id');
 | 
			
		||||
          should(data[0]).have.property('name', 'Crastin CE 2510');
 | 
			
		||||
          should(data[0]).have.property('supplier', 'Du Pont');
 | 
			
		||||
          should(data[0]).have.property('group', 'PBT');
 | 
			
		||||
          should(data[0]).have.property('mineral', '0');
 | 
			
		||||
          should(data[0]).have.property('glass_fiber', '30');
 | 
			
		||||
          should(data[0]).have.property('carbon_fiber', '0');
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,8 @@ import _ from 'lodash';
 | 
			
		||||
import MaterialValidate from './validate/material';
 | 
			
		||||
import MaterialModel from '../models/material'
 | 
			
		||||
import SampleModel from '../models/sample';
 | 
			
		||||
import MaterialGroupsModel from '../models/material_groups';
 | 
			
		||||
import MaterialSuppliersModel from '../models/material_suppliers';
 | 
			
		||||
import MaterialGroupModel from '../models/material_groups';
 | 
			
		||||
import MaterialSupplierModel from '../models/material_suppliers';
 | 
			
		||||
import IdValidate from './validate/id';
 | 
			
		||||
import res400 from './validate/res400';
 | 
			
		||||
import mongoose from 'mongoose';
 | 
			
		||||
@@ -20,11 +20,7 @@ router.get('/materials', (req, res, next) => {
 | 
			
		||||
 | 
			
		||||
  MaterialModel.find({status:globals.status.validated}).populate('group_id').populate('supplier_id').lean().exec((err, data) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    console.log(data);
 | 
			
		||||
    data.forEach((material: any) => {  // map group and supplier
 | 
			
		||||
      material.group = material.group_id.name;
 | 
			
		||||
      material.supplier = material.supplier_id.name;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    res.json(_.compact(data.map(e => MaterialValidate.output(e))));  // validate all and filter null values from validation errors
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -34,10 +30,7 @@ router.get('/materials/:state(new|deleted)', (req, res, next) => {
 | 
			
		||||
 | 
			
		||||
  MaterialModel.find({status: globals.status[req.params.state]}).populate('group_id').populate('supplier_id').lean().exec((err, data) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    data.forEach((material: any) => {  // map group and supplier
 | 
			
		||||
      material.group = material.group_id.name;
 | 
			
		||||
      material.supplier = material.supplier_id.name;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    res.json(_.compact(data.map(e => MaterialValidate.output(e))));  // validate all and filter null values from validation errors
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -52,8 +45,6 @@ router.get('/material/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
      return res.status(404).json({status: 'Not found'});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.group = data.group_id.name;
 | 
			
		||||
    data.supplier = data.supplier_id.name;
 | 
			
		||||
    if (data.status === globals.status.deleted && !req.auth(res, ['maintain', 'admin'], 'all')) return;  // deleted materials only available for maintain/admin
 | 
			
		||||
    res.json(MaterialValidate.output(data));
 | 
			
		||||
  });
 | 
			
		||||
@@ -62,7 +53,7 @@ router.get('/material/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
router.put('/material/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
  if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return;
 | 
			
		||||
 | 
			
		||||
  const {error, value: material} = MaterialValidate.input(req.body, 'change');
 | 
			
		||||
  let {error, value: material} = MaterialValidate.input(req.body, 'change');
 | 
			
		||||
  if (error) return res400(error, res);
 | 
			
		||||
 | 
			
		||||
  MaterialModel.findById(req.params.id).lean().exec(async (err, materialData: any) => {
 | 
			
		||||
@@ -75,13 +66,21 @@ router.put('/material/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
    if (material.hasOwnProperty('name') && material.name !== materialData.name) {
 | 
			
		||||
      if (!await nameCheck(material, res, next)) return;
 | 
			
		||||
    }
 | 
			
		||||
    if (material.hasOwnProperty('group')) {
 | 
			
		||||
      material = await groupResolve(material, next);
 | 
			
		||||
      if (!material) return;
 | 
			
		||||
    }
 | 
			
		||||
    if (material.hasOwnProperty('supplier')) {
 | 
			
		||||
      material = await supplierResolve(material, next);
 | 
			
		||||
      if (!material) return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // check for changes
 | 
			
		||||
    if (!_.isEqual(_.pick(IdValidate.stringify(materialData), _.keys(material)), material)) {
 | 
			
		||||
    if (!_.isEqual(_.pick(IdValidate.stringify(materialData), _.keys(material)), IdValidate.stringify(material))) {
 | 
			
		||||
      material.status = globals.status.new;  // set status to new
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await MaterialModel.findByIdAndUpdate(req.params.id, material, {new: true}).lean().exec((err, data) => {
 | 
			
		||||
    await MaterialModel.findByIdAndUpdate(req.params.id, material, {new: true}).populate('group_id').populate('supplier_id').lean().exec((err, data) => {
 | 
			
		||||
      if (err) return next(err);
 | 
			
		||||
      res.json(MaterialValidate.output(data));
 | 
			
		||||
    });
 | 
			
		||||
@@ -97,7 +96,7 @@ router.delete('/material/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
    if (data.length) {
 | 
			
		||||
      return res.status(400).json({status: 'Material still in use'});
 | 
			
		||||
    }
 | 
			
		||||
    MaterialModel.findByIdAndUpdate(req.params.id, {status:globals.status.deleted}).lean().exec((err, data) => {
 | 
			
		||||
    MaterialModel.findByIdAndUpdate(req.params.id, {status:globals.status.deleted}).populate('group_id').populate('supplier_id').lean().exec((err, data) => {
 | 
			
		||||
      if (err) return next(err);
 | 
			
		||||
      if (data) {
 | 
			
		||||
        res.json({status: 'OK'});
 | 
			
		||||
@@ -122,17 +121,24 @@ router.put('/material/restore/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.post('/material/new', async (req, res, next) => {  // TODO: check supplier and group, also for PUT and DELETE
 | 
			
		||||
router.post('/material/new', async (req, res, next) => {
 | 
			
		||||
  if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return;
 | 
			
		||||
 | 
			
		||||
  const {error, value: material} = MaterialValidate.input(req.body, 'new');
 | 
			
		||||
  let {error, value: material} = MaterialValidate.input(req.body, 'new');
 | 
			
		||||
  if (error) return res400(error, res);
 | 
			
		||||
 | 
			
		||||
  if (!await nameCheck(material, res, next)) return;
 | 
			
		||||
  material = await groupResolve(material, next);
 | 
			
		||||
  if (!material) return;
 | 
			
		||||
  material = await supplierResolve(material, next);
 | 
			
		||||
  if (!material) return;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  material.status = globals.status.new;  // set status to new
 | 
			
		||||
  await new MaterialModel(material).save((err, data) => {
 | 
			
		||||
  await new MaterialModel(material).save(async (err, data) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    await data.populate('group_id').populate('supplier_id').execPopulate().catch(err => next(err));
 | 
			
		||||
    if (data instanceof Error) return;
 | 
			
		||||
    res.json(MaterialValidate.output(data.toObject()));
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -140,7 +146,7 @@ router.post('/material/new', async (req, res, next) => {  // TODO: check supplie
 | 
			
		||||
router.get('/material/groups', (req, res, next) => {
 | 
			
		||||
  if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return;
 | 
			
		||||
 | 
			
		||||
  MaterialGroupsModel.find().lean().exec((err, data: any) => {
 | 
			
		||||
  MaterialGroupModel.find().lean().exec((err, data: any) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
 | 
			
		||||
    res.json(_.compact(data.map(e => MaterialValidate.outputGroups(e.name))));  // validate all and filter null values from validation errors
 | 
			
		||||
@@ -150,7 +156,7 @@ router.get('/material/groups', (req, res, next) => {
 | 
			
		||||
router.get('/material/suppliers', (req, res, next) => {
 | 
			
		||||
  if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return;
 | 
			
		||||
 | 
			
		||||
  MaterialSuppliersModel.find().lean().exec((err, data: any) => {
 | 
			
		||||
  MaterialSupplierModel.find().lean().exec((err, data: any) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
 | 
			
		||||
    res.json(_.compact(data.map(e => MaterialValidate.outputSuppliers(e.name))));  // validate all and filter null values from validation errors
 | 
			
		||||
@@ -170,3 +176,19 @@ async function nameCheck (material, res, next) {  // check if name was already t
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function groupResolve (material, next) {
 | 
			
		||||
  const groupData = await MaterialGroupModel.findOneAndUpdate({name: material.group}, {name: material.group}, {upsert: true, new: true}).lean().exec().catch(err => next(err)) as any;
 | 
			
		||||
  if (groupData instanceof Error) return false;
 | 
			
		||||
  material.group_id = groupData._id;
 | 
			
		||||
  delete material.group;
 | 
			
		||||
  return material;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function supplierResolve (material, next) {
 | 
			
		||||
  const supplierData = await MaterialSupplierModel.findOneAndUpdate({name: material.supplier}, {name: material.supplier}, {upsert: true, new: true}).lean().exec().catch(err => next(err)) as any;
 | 
			
		||||
  if (supplierData instanceof Error) return false;
 | 
			
		||||
  material.supplier_id = supplierData._id;
 | 
			
		||||
  delete material.supplier;
 | 
			
		||||
  return material;
 | 
			
		||||
}
 | 
			
		||||
@@ -5,7 +5,6 @@ import TemplateMeasurementModel from '../models/measurement_template';
 | 
			
		||||
import TestHelper from "../test/helper";
 | 
			
		||||
 | 
			
		||||
// TODO: do not allow usage of old templates for new samples
 | 
			
		||||
// TODO: remove number_prefix
 | 
			
		||||
// TODO: template parameters are not allowed to be condition_template
 | 
			
		||||
 | 
			
		||||
describe('/template', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,8 @@ export default class MaterialValidate {  // validate input for material
 | 
			
		||||
 | 
			
		||||
  static output (data) {  // validate output and strip unwanted properties, returns null if not valid
 | 
			
		||||
    data = IdValidate.stringify(data);
 | 
			
		||||
    data.group = data.group_id.name;
 | 
			
		||||
    data.supplier = data.supplier_id.name;
 | 
			
		||||
    const {value, error} = Joi.object({
 | 
			
		||||
      _id: IdValidate.get(),
 | 
			
		||||
      name: this.material.name,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user