Skip to content

Commit

Permalink
LF-4380 Address PR feedback about desired keys, groupIdMap, oneTruthy…
Browse files Browse the repository at this point in the history
… naming, handling false and zero
  • Loading branch information
Duncan-Brain committed Oct 19, 2024
1 parent d196bec commit c76bc27
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 73 deletions.
37 changes: 19 additions & 18 deletions packages/api/src/controllers/animalBatchController.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,25 @@ const animalBatchController = {
const typeIdsMap = {};
const typeBreedIdsMap = {};

const desiredKeys = [
'id',
'count',
'custom_breed_id',
'custom_type_id',
'default_breed_id',
'default_type_id',
'name',
'notes',
'photo_url',
'organic_status',
'supplier',
'price',
'sex_detail',
'origin_id',
'group_ids',
'animal_batch_use_relationships',
];

// select only allowed properties to edit
for (const animalBatch of req.body) {
await checkAndAddCustomTypeAndBreed(
Expand All @@ -118,24 +137,6 @@ const animalBatchController = {
trx,
);

const desiredKeys = [
'id',
'count',
'custom_breed_id',
'custom_type_id',
'default_breed_id',
'default_type_id',
'name',
'notes',
'photo_url',
'organic_status',
'supplier',
'price',
'sex_detail',
'origin_id',
'group_ids',
'animal_batch_use_relationships',
];
const keysExisting = desiredKeys.filter((key) => key in animalBatch);
const data = _pick(animalBatch, keysExisting);

Expand Down
65 changes: 32 additions & 33 deletions packages/api/src/controllers/animalController.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,8 @@ const animalController = {
);

// Format group_ids
const groupIdMap =
individualAnimalResult.group_ids =
individualAnimalResult.group_ids?.map((group) => group.animal_group_id) || [];
individualAnimalResult.group_ids = groupIdMap;

result.push(individualAnimalResult);
}
Expand All @@ -115,6 +114,36 @@ const animalController = {
const typeIdsMap = {};
const typeBreedIdsMap = {};

const desiredKeys = [
'id',
'custom_breed_id',
'custom_type_id',
'default_breed_id',
'default_type_id',
'sex_id',
'name',
'birth_date',
'identifier',
'identifier_color_id',
'identifier_placement_id',
'identifier_type_id',
'identifier_type_other',
'origin_id',
'dam',
'sire',
'brought_in_date',
'weaning_date',
'notes',
'photo_url',
'organic_status',
'supplier',
'price',
'sex_detail',
'origin_id',
'group_ids',
'animal_use_relationships',
];

// select only allowed properties to edit
for (const animal of req.body) {
await checkAndAddCustomTypeAndBreed(
Expand All @@ -125,38 +154,8 @@ const animalController = {
farm_id,
trx,
);
// TODO: Comment out for animals v1?
await checkAndAddGroup(req, animal, farm_id, trx);

const desiredKeys = [
'id',
'custom_breed_id',
'custom_type_id',
'default_breed_id',
'default_type_id',
'sex_id',
'name',
'birth_date',
'identifier',
'identifier_color_id',
'identifier_placement_id',
'identifier_type_id',
'identifier_type_other',
'origin_id',
'dam',
'sire',
'brought_in_date',
'weaning_date',
'notes',
'photo_url',
'organic_status',
'supplier',
'price',
'sex_detail',
'origin_id',
'group_ids',
'animal_use_relationships',
];
await checkAndAddGroup(req, animal, farm_id, trx);

const keysExisting = desiredKeys.filter((key) => key in animal);
const data = _pick(animal, keysExisting);
Expand Down
39 changes: 21 additions & 18 deletions packages/api/src/middleware/validation/checkAnimalOrBatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import { Model, transaction } from 'objection';
import { handleObjectionError } from '../../util/errorCodes.js';
import { oneExists, oneTruthy, setFalsyValuesToNull } from '../../util/middleware.js';
import { someExists, someTruthy, setFalsyValuesToNull } from '../../util/middleware.js';
import {
customError,
checkIsArray,
Expand Down Expand Up @@ -77,13 +77,13 @@ const checkAnimalType = async (animalOrBatch, farm_id, creating = true) => {
const { default_type_id, custom_type_id, type_name } = animalOrBatch;
const typeKeyOptions = ['default_type_id', 'custom_type_id', 'type_name'];
// Skip if all undefined or editing (!creating)
if (creating || oneTruthy([default_type_id, custom_type_id, type_name])) {
if (creating || someTruthy([default_type_id, custom_type_id, type_name])) {
checkExactlyOneIsProvided(
[default_type_id, custom_type_id, type_name],
'default_type_id, custom_type_id, or type_name',
);
}
if (!creating && oneExists(typeKeyOptions, animalOrBatch)) {
if (!creating && someExists(typeKeyOptions, animalOrBatch)) {
// Overwrite with null in db if editing
setFalsyValuesToNull(typeKeyOptions, animalOrBatch);
}
Expand Down Expand Up @@ -141,7 +141,7 @@ const checkCustomBreedMatchesType = (
const typeKeyOptions = ['default_type_id', 'custom_type_id', 'type_name'];

// If not editing type, check record type
if (!oneExists(typeKeyOptions, animalOrBatch) && animalOrBatchRecord) {
if (!someExists(typeKeyOptions, animalOrBatch) && animalOrBatchRecord) {
defaultTypeId = animalOrBatchRecord.default_type_id;
customTypeId = animalOrBatchRecord.custom_type_id;
}
Expand Down Expand Up @@ -174,43 +174,43 @@ const checkAnimalBreed = async (

// Check if breed is present
if (
(creating && oneExists(breedKeyOptions, animalOrBatch)) ||
oneTruthy([default_breed_id, custom_breed_id, breed_name])
(creating && someExists(breedKeyOptions, animalOrBatch)) ||
someTruthy([default_breed_id, custom_breed_id, breed_name])
) {
checkExactlyOneIsProvided(
[default_breed_id, custom_breed_id, breed_name],
'default_breed_id, custom_breed_id, or breed_name',
);
}
// Check if breed is present
if (!creating && oneExists(breedKeyOptions, animalOrBatch)) {
if (!creating && someExists(breedKeyOptions, animalOrBatch)) {
// Overwrite with null in db if editing
setFalsyValuesToNull(breedKeyOptions, animalOrBatch);
}

if (
oneExists(breedKeyOptions, animalOrBatch) &&
!oneTruthy([default_breed_id, custom_breed_id, breed_name])
someExists(breedKeyOptions, animalOrBatch) &&
!someTruthy([default_breed_id, custom_breed_id, breed_name])
) {
// do nothing if nulling breed
} else {
// Check if default breed or default type is present
if (
(oneExists(breedKeyOptions, animalOrBatch) && default_breed_id) ||
(oneExists(typeKeyOptions, animalOrBatch) && default_type_id)
(someExists(breedKeyOptions, animalOrBatch) && default_breed_id) ||
(someExists(typeKeyOptions, animalOrBatch) && default_type_id)
) {
await checkDefaultBreedMatchesType(animalOrBatchRecord, default_breed_id, default_type_id);
}
// Check if custom breed or custom type is present
if (
(oneExists(breedKeyOptions, animalOrBatch) && custom_breed_id && !type_name) ||
(oneExists(typeKeyOptions, animalOrBatch) &&
(someExists(breedKeyOptions, animalOrBatch) && custom_breed_id && !type_name) ||
(someExists(typeKeyOptions, animalOrBatch) &&
(default_type_id || custom_type_id) &&
!breed_name)
) {
let customBreed;
// Find customBreed if exists
if (oneExists(breedKeyOptions, animalOrBatch) && custom_breed_id) {
if (someExists(breedKeyOptions, animalOrBatch) && custom_breed_id) {
checkIdIsNumber(custom_breed_id);
customBreed = await CustomAnimalBreedModel.query()
.whereNotDeleted()
Expand Down Expand Up @@ -296,7 +296,7 @@ const checkAnimalUseRelationship = async (animalOrBatch, animalOrBatchKey) => {

const checkAnimalOrigin = async (animalOrBatch, creating = true) => {
const { origin_id, brought_in_date } = animalOrBatch;
if (oneExists(['origin_id', 'brought_in_date'], animalOrBatch)) {
if (someExists(['origin_id', 'brought_in_date'], animalOrBatch)) {
const broughtInOrigin = await AnimalOriginModel.query().where({ key: 'BROUGHT_IN' }).first();
// Overwrite date with null in db if editing origin_id
if (!creating && origin_id != broughtInOrigin.id) {
Expand All @@ -312,7 +312,7 @@ const checkAnimalOrigin = async (animalOrBatch, creating = true) => {
const checkAnimalIdentifier = async (animalOrBatch, animalOrBatchKey, creating = true) => {
if (animalOrBatchKey === 'animal') {
const { identifier_type_id, identifier_type_other } = animalOrBatch;
if (oneExists(['identifier_type_id', 'identifier_type_other'], animalOrBatch)) {
if (someExists(['identifier_type_id', 'identifier_type_other'], animalOrBatch)) {
const otherIdentifier = await AnimalIdentifierType.query().where({ key: 'OTHER' }).first();
// Overwrite date with null in db if editing origin_id
if (!creating && identifier_type_id != otherIdentifier.id) {
Expand Down Expand Up @@ -344,7 +344,10 @@ const checkAndAddCustomTypesOrBreeds = (
let defaultBreedId = default_breed_id;
let customBreedId = custom_breed_id;

if (!oneExists(['default_breed_id', 'custom_breed_id'], animalOrBatch) && animalOrBatchRecord) {
if (
!someExists(['default_breed_id', 'custom_breed_id'], animalOrBatch) &&
animalOrBatchRecord
) {
defaultBreedId = animalOrBatchRecord.default_breed_id;
customBreedId = animalOrBatchRecord.custom_breed_id;
}
Expand All @@ -361,7 +364,7 @@ const checkAndAddCustomTypesOrBreeds = (
let defaultTypeId = default_type_id;
let customTypeId = custom_type_id;

if (!oneExists(['default_type_id', 'custom_type_id'], animalOrBatch) && animalOrBatchRecord) {
if (!someExists(['default_type_id', 'custom_type_id'], animalOrBatch) && animalOrBatchRecord) {
defaultTypeId = animalOrBatchRecord.default_type_id;
customTypeId = animalOrBatchRecord.custom_type_id;
}
Expand Down
10 changes: 6 additions & 4 deletions packages/api/src/util/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ export const notExactlyOneValue = (values) => {
};

// Checks an array of object keys against object -- at least one of the properties is defined
export const oneExists = (keys, object) => {
export const someExists = (keys, object) => {
return keys.some((key) => key in object);
};

// Checks an array for at least one truthy value
export const oneTruthy = (values) => values.some((value) => !!value);
export const someTruthy = (values) => values.some((value) => !!value);

// Sets falsy values to null for editing values that may have values for exclusive constraints -- does not handle zeros yet
// Sets falsy values to null for editing values that may have values for exclusive constraints
export const setFalsyValuesToNull = (array, obj) => {
for (const val of array) {
obj[val] = obj[val] || null;
if (obj[val] !== 0 && obj[val] !== false) {
obj[val] ??= null;
}
}
};

0 comments on commit c76bc27

Please sign in to comment.