bridge-node-server/node_server/utils/postcodes.js
Martin Donnelly 57bd6c8e6a init
2018-06-24 21:15:03 +01:00

102 lines
2.9 KiB
JavaScript

/**
* Utils for looking up postcodes from addresses
*/
'use strict';
const debug = require('debug')('utils:postcodes');
const Q = require('q');
const config = require(global.configFile);
const idealPostcodes = require('ideal-postcodes')(config.idealPostcodesKey);
const UkClearAddressing = require('uk-clear-addressing');
const ERRORS = {
UNSPECIFIED: 'Unspecified error'
};
module.exports = {
ERRORS,
postcodeLookup
};
/**
* Runs a postcode lookup and returns a list of addresses that could match that
* postcode.
*
* @param {string} postcode - the postcode to lookup addresses for
* @returns {Promise} - promise for array of addressses
*/
function postcodeLookup(postcode) {
debug('Postcode Lookup: ', postcode);
return Q.ninvoke(
idealPostcodes,
'lookupPostcode',
postcode
).then((addresses) => {
const formatted = [];
for (let i = 0; i < addresses.length; ++i) {
formatted.push(pafToBridgeAddress(addresses[i]));
}
debug('Formatted:', formatted);
return formatted;
}).catch(() => {
//
// The API doesn't really make it possible to differentatiate errors at
// this time.
//
const newError = ERRORS.UNSPECIFIED;
return Q.reject(newError);
});
}
/**
* Converst a PAF (Royal Mail Postcode Address File) format address to a
* Bridge style one.
*
* @param {Object} pafAddr - the address is PAF format
* @returns {Object} - the address in Bridge format
*/
function pafToBridgeAddress(pafAddr) {
//
// Use the uk-clear-addressing module to do most of the work for us
//
const clearAddr = new UkClearAddressing(pafAddr).formattedAddress();
// Disable the variable case error because uk-clear-addressing uses snake case
// jshint -W106
const bridgeAddress = {
Town: clearAddr.post_town,
PostCode: clearAddr.postcode,
Country: 'United Kingdom'
};
if (clearAddr.line_3) {
//
// The address has 3 lines, so put the first one in BuildingNameFlat
//
bridgeAddress.BuildingNameFlat = clearAddr.line_1;
bridgeAddress.Address1 = clearAddr.line_2;
bridgeAddress.Address2 = clearAddr.line_3;
} else if (clearAddr.line_1 === pafAddr.sub_building_name) {
//
// We differentiate between "BuildingNameFlat" and Address1, whereas
// UkClearAddressing doesn't. So if line_1 is just the sub building name,
// then put that in flat, and move line 2 up.
//
bridgeAddress.BuildingNameFlat = clearAddr.line_1;
bridgeAddress.Address1 = clearAddr.line_2;
} else {
//
// This address has at most 2 lines, so just use the main fields.
//
bridgeAddress.Address1 = clearAddr.line_1;
bridgeAddress.Address2 = clearAddr.line_2;
}
//
// Convert the fields accross to our names for them.
//
return bridgeAddress;
}