diff --git a/src/models/units/units.modeltypes.cjs b/src/models/units/units.modeltypes.cjs index ff28d0bd..e5a75c0a 100644 --- a/src/models/units/units.modeltypes.cjs +++ b/src/models/units/units.modeltypes.cjs @@ -15,6 +15,7 @@ module.exports = { countryJurisdictionOfOwner: Sequelize.STRING, inCountryJurisdictionOfOwner: Sequelize.STRING, serialNumberBlock: Sequelize.STRING, + customSerialNumberPattern: Sequelize.STRING, unitIdentifier: Sequelize.STRING, unitType: Sequelize.STRING, intendedBuyerOrgUid: Sequelize.STRING, diff --git a/src/utils/helpers.js b/src/utils/helpers.js index 43a68c88..5667de7e 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -52,10 +52,21 @@ export const columnsToInclude = (userColumns, foreignKeys) => { }; }; -export const transformSerialNumberBlock = (serialNumberBlock) => { - const blocks = serialNumberBlock.split('-'); - const blockStart = Number(blocks[0].split(/(\d+)/)[1]); - const blockEnd = Number(blocks[1].split(/(\d+)/)[1]); +export const defaultSerialNumberPattern = /[.*\D]+([0-9]+)+[-][.*\D]+([0-9]+)$/; + +export const transformSerialNumberBlock = ( + serialNumberBlock, + // serial number format: ABC1000-ABC1010 + serialNumberPattern = defaultSerialNumberPattern, +) => { + const unitBlocks = serialNumberBlock.match(serialNumberPattern); + + if (!unitBlocks) { + return [null, null, null]; + } + + const blockStart = Number(unitBlocks[1]); + const blockEnd = Number(unitBlocks[2]); return [blockStart, blockEnd, blockEnd - blockStart]; }; @@ -63,8 +74,10 @@ export const createSerialNumberStr = ( originalSerialNumberBlock, blockStart, blockEnd, + serialNumberPattern = defaultSerialNumberPattern, ) => { - const blocks = originalSerialNumberBlock.split('-'); - const serialNumberPrefix = blocks[0].split(/(\d+)/)[0]; - return `${serialNumberPrefix}${blockStart}-${serialNumberPrefix}${blockEnd}`; + const unitBlocks = originalSerialNumberBlock.match(serialNumberPattern); + return unitBlocks[0] + .replace(unitBlocks[1], blockStart) + .replace(unitBlocks[2], blockEnd); }; diff --git a/src/validations/units.validations.js b/src/validations/units.validations.js index 20c1a1ec..bc35eaf0 100644 --- a/src/validations/units.validations.js +++ b/src/validations/units.validations.js @@ -2,23 +2,35 @@ import Joi from 'joi'; import { transformSerialNumberBlock } from '../utils/helpers'; import { newVintageScheme, existingVintageSchema } from './vintages.validation'; +const customSerialNumberValidator = (obj, helper) => { + const { serialNumberBlock, customSerialNumberPattern } = obj; + + // eslint-disable-next-line no-unused-vars + const [_, __, unitCount] = transformSerialNumberBlock( + serialNumberBlock, + customSerialNumberPattern || undefined, + ); + + if (!unitCount) { + return helper.message( + `serialNumberBlock could not be parsed, invalid pattern found`, + ); + } + + if (unitCount < 1) { + return helper.message( + `serialNumberBlock must have a positive non-zero number, received ${unitCount}`, + ); + } + return obj; +}; + const unitsBaseSchema = { countryJurisdictionOfOwner: Joi.string().required(), inCountryJurisdictionOfOwner: Joi.string().optional(), // must be in the form ABC123-XYZ456 - serialNumberBlock: Joi.string() - .regex(/[.*\D]+[0-9]+[-][.*\D]+[0-9]+$/) - .custom((value, helper) => { - const [_, __, unitCount] = transformSerialNumberBlock(value); - if (unitCount < 1) { - return helper.message( - `serialNumberBlock must have a positive non-zero number, received ${unitCount}`, - ); - } else { - return value; - } - }) - .required(), + serialNumberBlock: Joi.string().required(), + customSerialNumberPattern: Joi.string().optional(), unitIdentifier: Joi.string().required(), unitType: Joi.string().valid('heard reduction', 'removal').required(), intendedBuyerOrgUid: Joi.string().optional(), @@ -45,7 +57,7 @@ const unitsBaseSchema = { export const unitsPostSchema = Joi.object({ ...unitsBaseSchema, -}); +}).custom(customSerialNumberValidator); export const unitsGetQuerySchema = Joi.object() .keys({ @@ -61,7 +73,7 @@ export const unitsGetQuerySchema = Joi.object() export const unitsUpdateSchema = Joi.object({ warehouseUnitId: Joi.string().required(), ...unitsBaseSchema, -}); +}).custom(customSerialNumberValidator); export const unitsDeleteSchema = Joi.object({ warehouseUnitId: Joi.string().required(),