diff --git a/api/sample.yaml b/api/sample.yaml index 1359d23..6816022 100644 --- a/api/sample.yaml +++ b/api/sample.yaml @@ -52,7 +52,8 @@ - name: filters[] description: "the filters to apply as an array of URIComponent encoded objects in the form {mode: 'eq/ne/lt/lte/gt/gte/in/nin/stringin', field: 'material.m', values: ['15']} using - encodeURIComponent(JSON.stringify({}))" + encodeURIComponent(JSON.stringify({}))
Use {mode: 'eq', field: 'condition', values: [{}]} and + {mode: 'eq', field: 'measurements', values: [null]} to filter for samples without condition or measurements" in: query schema: type: array diff --git a/src/routes/sample.spec.ts b/src/routes/sample.spec.ts index 16107c9..9a53e29 100644 --- a/src/routes/sample.spec.ts +++ b/src/routes/sample.spec.ts @@ -440,6 +440,48 @@ describe('/sample', () => { done(); }); }); + it('filters for empty conditions', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/samples?status[]=new&status[]=validated&fields[]=number&fields[]=condition&filters[]=%7B%22mode%22%3A%22eq%22%2C%22field%22%3A%22condition%22%2C%22values%22%3A%5B%7B%7D%5D%7D', + auth: {basic: 'janedoe'}, + httpStatus: 200 + }).end((err, res) => { + if (err) return done(err); + const json = require('../test/db.json'); + should(res.body).have.lengthOf( + json.collections.samples + .filter(e => e.status !== 'deleted') + .filter(e => Object.keys(e.condition).length === 0) + .length + ); + should(res.body).matchEach(sample => { + should(sample.condition).be.eql({}); + }); + done(); + }); + }); + it('filters for samples without measurements', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/samples?status[]=new&status[]=validated&fields[]=number&fields[]=_id&filters[]=%7B%22mode%22%3A%22eq%22%2C%22field%22%3A%22measurements%22%2C%22values%22%3A%5Bnull%5D%7D', + auth: {basic: 'janedoe'}, + httpStatus: 200 + }).end((err, res) => { + if (err) return done(err); + const json = require('../test/db.json'); + should(res.body).have.lengthOf( + json.collections.samples + .filter(e => e.status !== 'deleted') + .filter(e => !json.collections.measurements.find(el => el.sample_id.toString() === e._id.toString())) + .length + ); + should(res.body).matchEach(sample => { + should(json.collections.measurements.find(el => el.sample_id.toString() === sample._id)).be.eql(undefined); + }); + done(); + }); + }); it('returns comment fields', done => { TestHelper.request(server, done, { method: 'get', diff --git a/src/routes/sample.ts b/src/routes/sample.ts index 06c2381..d5bc207 100644 --- a/src/routes/sample.ts +++ b/src/routes/sample.ts @@ -219,6 +219,15 @@ router.get('/samples', async (req, res, next) => { } } + if (sortFilterKeys.find(e => e === 'measurements')) { // filter for samples without measurements + queryPtr.push({$lookup: { + from: 'measurements', let: {sId: '$_id'}, + pipeline: [{$match:{$expr:{$and:[{$eq:['$sample_id','$$sId']}]}}}, {$project: {_id: true}}], + as: 'measurementCount' + }}, + {$match: {measurementCount: {$size: 0}}} + ); + } const measurementFilterFields = _.uniq(sortFilterKeys.filter(e => /measurements\./.test(e)) .map(e => e.split('.')[1])); // filter measurement names and remove duplicates from parameters if (sortFilterKeys.find(e => /measurements\./.test(e))) { // add measurement fields diff --git a/src/routes/validate/sample.ts b/src/routes/validate/sample.ts index 54f7bb4..0d50576 100644 --- a/src/routes/validate/sample.ts +++ b/src/routes/validate/sample.ts @@ -98,6 +98,7 @@ export default class SampleValidate { 'user_id', 'material._id', 'material.numbers', + 'measurements', `measurements.${globals.spectrum.spectrum}.${globals.spectrum.dpt}`, ]; @@ -226,6 +227,12 @@ export default class SampleValidate { }); field = 'value'; } + else if (field === 'measurements') { + validator = Joi.object({ + value: Joi.object({}).allow(null).disallow({}) + }); + field = 'value'; + } else if (field === 'notes.comment') { field = 'comment'; validator = this.sample.notes @@ -234,6 +241,7 @@ export default class SampleValidate { validator = Joi.object(this.sample); } const {value, error} = validator.validate({[field]: e}); + console.log(error); if (error) throw error; // reject invalid values return value[field]; });