1 | const _ = {};
|
2 | _.findIndex = require('lodash/findIndex');
|
3 |
|
4 | const util = require('util');
|
5 |
|
6 | const printAddress = function(address) {
|
7 | return address.street + (address.houseNumber ? ' ' + address.houseNumber : '') + (address.mailboxNumber ? ' ' + address.mailboxNumber : '') +
|
8 | ', ' + address.zipCode + ' ' + address.subCity;
|
9 | };
|
10 |
|
11 | const addSubCityHref = async function (address, api, dateUtils = require('../date-utils')) {
|
12 | const thisSubCityClean = address.subCity.split('(')[0].trim();
|
13 | var subCities = null;
|
14 | if(address.nisCode && !address.cityHref) {
|
15 | address.cityHref = '/sam/commons/cities/'+address.nisCode;
|
16 | }
|
17 | if(!address.cityHref && address.streetHref) {
|
18 | try {
|
19 | const street = await api.get(address.streetHref);
|
20 | if(dateUtils.isBefore(street.endDate, dateUtils.getNow())) {
|
21 | address.cityHref = street.city.href;
|
22 | }
|
23 | } catch(error) {
|
24 | console.warn('street with permalink ' + address.streetHref + ' can not be found in the API');
|
25 | }
|
26 | }
|
27 | if(address.cityHref) {
|
28 | subCities = await api.getAll('/sam/commons/subcities', {city: address.cityHref}, {expand: 'city'});
|
29 |
|
30 | if(subCities.length === 0) {
|
31 | subCities = await api.getAll('/sam/commons/subcities', {nameContains: thisSubCityClean}, {expand: 'city'});
|
32 | }
|
33 | } else {
|
34 | subCities = await api.getAll('/sam/commons/subcities', {nameContains: thisSubCityClean}, {expand: 'city'});
|
35 | }
|
36 | var matches = [];
|
37 | var checkedSubCities = null;
|
38 | subCities.forEach(function(subCity) {
|
39 | checkedSubCities = checkedSubCities ? checkedSubCities + ', ' : '';
|
40 | checkedSubCities += subCity.name + ' [ ' + subCity.city.$$expanded.name + '] ' + JSON.stringify(subCity.zipCodes);
|
41 | if(subCity.name.split('(')[0].trim().toLowerCase() === thisSubCityClean.toLowerCase()) {
|
42 | if(address.zipCode) {
|
43 |
|
44 | let index = _.findIndex(subCity.zipCodes, function(zipCode) {
|
45 | return zipCode.toString() === address.zipCode;
|
46 | });
|
47 | if(index > -1) {
|
48 | matches.push(subCity);
|
49 | }
|
50 | } else {
|
51 | matches.push(subCity);
|
52 | }
|
53 | }
|
54 | });
|
55 | if(matches.length > 1) {
|
56 | console.warn('multiple subCity matches for ' + address.subCity);
|
57 | if(address.nisCode) {
|
58 | checkedSubCities += ' in niscode '+ address.nisCode;
|
59 | }
|
60 | console.warn('checked for the following sub cities: ' + checkedSubCities);
|
61 | } else if(matches.length === 0) {
|
62 | console.warn('no subCity match could be found for ' + address.street + ' ' + address.houseNumber + ', ' + address.zipCode + ' ' + address.subCity);
|
63 | if(address.nisCode) {
|
64 | checkedSubCities += ' in niscode '+ address.nisCode;
|
65 | }
|
66 | console.warn('checked for the following sub cities: ' + checkedSubCities);
|
67 | } else {
|
68 | address.subCityHref = matches[0].$$meta.permalink;
|
69 | if(!address.city) {
|
70 | address.city = matches[0].city.$$expanded.name;
|
71 | }
|
72 | address.cityHref = matches[0].city.href;
|
73 | }
|
74 | };
|
75 |
|
76 | const addStreetHref = async function(address, api, dateUtils = require('../date-utils'), changeStreetName = false) {
|
77 | if(!address.nisCode && !address.cityHref && !address.subCityHref) {
|
78 | await addSubCityHref(address, api);
|
79 | }
|
80 | |
81 |
|
82 |
|
83 |
|
84 | if(!address.cityHref && address.nisCode) {
|
85 | address.cityHref = '/sam/commons/cities/'+address.niscode;
|
86 | }
|
87 | if(!address.cityHref) {
|
88 | console.warn('no street match could be found for ' + address.street + ' in ' + address.subCity + ' because there is no city in the address.');
|
89 | return;
|
90 | }
|
91 | const streets = await api.getAll('/sam/commons/streets', {city: address.cityHref, endDateAfter: dateUtils.getNow()});
|
92 | const matches = [];
|
93 | streets.forEach(function(street) {
|
94 | if(isStreetNameMatch(street.name, address.street)) {
|
95 | matches.push(street);
|
96 | }
|
97 | });
|
98 | if(matches.length > 1) {
|
99 | let nbOfExactMatches = 0;
|
100 | let exactMatch = null;
|
101 | matches.forEach(street => {
|
102 | if(street.name === address.street) {
|
103 | nbOfExactMatches++;
|
104 | exactMatch = street;
|
105 | }
|
106 | });
|
107 | if(nbOfExactMatches === 1) {
|
108 | address.streetHref = exactMatch.$$meta.permalink;
|
109 | if(changeStreetName) {
|
110 | address.street = exactMatch.name;
|
111 | }
|
112 | } else {
|
113 | console.warn('multiple street matches for ' + address.street + ' in ' + address.subCity);
|
114 | }
|
115 | } else if(matches.length === 0) {
|
116 | console.warn('no street match could be found for ' + address.street + ' in ' + address.subCity);
|
117 | } else {
|
118 | address.streetHref = matches[0].$$meta.permalink;
|
119 | if(changeStreetName) {
|
120 | address.street = matches[0].name;
|
121 | }
|
122 | }
|
123 | };
|
124 |
|
125 | const isSameSubcity = function (a, b) {
|
126 | return a.subCity.replace(/\s?\(.+\)/g, '').toLowerCase() === b.subCity.replace(/\s?\(.+\)/g, '').toLowerCase();
|
127 | };
|
128 |
|
129 | const isSameHouseNumberAndMailbox = function (a, b) {
|
130 | var x =
|
131 | (
|
132 | (!a.houseNumber && !b.houseNumber) ||
|
133 | (
|
134 | a.houseNumber && b.houseNumber &&
|
135 | a.houseNumber.toLowerCase()
|
136 | .replace(/^[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]/g, '')
|
137 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([0-9])/g, '_$1')
|
138 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([a-zA-Z])/g, '$1')
|
139 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]$/g, '') ===
|
140 | b.houseNumber.toLowerCase()
|
141 | .replace(/^[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]/g, '')
|
142 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([0-9])/g, '_$1')
|
143 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([a-zA-Z])/g, '$1')
|
144 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]$/g, '')
|
145 | )
|
146 | ) &&
|
147 | (
|
148 | ((!a.mailboxNumber || a.mailboxNumber.trim() === '') && (!b.mailboxNumber || b.mailboxNumber.trim() === '')) ||
|
149 | ( a.mailboxNumber && b.mailboxNumber &&
|
150 | a.mailboxNumber.toLowerCase()
|
151 | .replace(/^[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]/g, '')
|
152 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([0-9])/g, '_$1')
|
153 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([a-zA-Z])/g, '$1')
|
154 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]$/g, '') ===
|
155 | b.mailboxNumber.toLowerCase()
|
156 | .replace(/^[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]/g, '')
|
157 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([0-9])/g, '_$1')
|
158 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]([a-zA-Z])/g, '$1')
|
159 | .replace(/[\_\s\/\.\-\(\)]*[\_\s\/\.\-\(\)]$/g, '')
|
160 | )
|
161 | );
|
162 | return x;
|
163 | };
|
164 |
|
165 | const isStreetNameMatch = function (a, b) {
|
166 | const bracesPattern = /(.*)\s\((.*)\)/g;
|
167 | if(a.match(bracesPattern)) {
|
168 | return isStreetNameMatch(a.replace(bracesPattern, '$1'), b) || isStreetNameMatch(a.replace(bracesPattern, '$2 $1'), b);
|
169 | }
|
170 | if(b.match(bracesPattern)) {
|
171 | return isStreetNameMatch(a, b.replace(bracesPattern, '$1')) || isStreetNameMatch(a , b.replace(bracesPattern, '$2 $1'));
|
172 | }
|
173 | const aWords = a.replace(/\.([A-Z])/g, '. $1').toLowerCase().replace(/st\-/g, 'sint-').replace(/st\.\s/g, 'sint ').replace(/st\./g, 'sint ').replace(/[\-]/g, ' ').split(' ');
|
174 | const bWords = b.replace(/\.([A-Z])/g, '. $1').toLowerCase().replace(/st\-/g, 'sint-').replace(/st\.\s/g, 'sint ').replace(/st\./g, 'sint ').replace(/[\-]/g, ' ').split(' ');
|
175 | if(aWords.join('') === bWords.join('')) {
|
176 | return true;
|
177 | } else if(aWords.length === bWords.length) {
|
178 | for(var i = 0; i < aWords.length; i++) {
|
179 | if(!aWords[i].endsWith('.') && !bWords[i].endsWith('.')) {
|
180 | if(aWords[i] !== bWords[i]) {
|
181 | return false;
|
182 | }
|
183 | } else if(aWords[i].endsWith('.') && bWords[i].endsWith('.')) {
|
184 | if(aWords[i].length === bWords[i].length) {
|
185 | if(aWords[i] !== bWords[i]) {
|
186 | return false;
|
187 | }
|
188 | } else if(aWords[i].length < bWords[i].length) {
|
189 | if(!bWords[i].startsWith(aWords[i].substring(0, aWords[i].length-1))) {
|
190 | return false;
|
191 | }
|
192 | } else {
|
193 | if(!aWords[i].startsWith(bWords[i].substring(0, bWords[i].length-1))) {
|
194 | return false;
|
195 | }
|
196 | }
|
197 | } else if(aWords[i].endsWith('.')) {
|
198 | if(!bWords[i].startsWith(aWords[i].substring(0, aWords[i].length-1))) {
|
199 | return false;
|
200 | }
|
201 | } else {
|
202 | if(!aWords[i].startsWith(bWords[i].substring(0, bWords[i].length-1))) {
|
203 | return false;
|
204 | }
|
205 | }
|
206 | }
|
207 | return true;
|
208 | }
|
209 | return false;
|
210 | };
|
211 |
|
212 | const isSameStreet = function (a, b) {
|
213 | var x = (a.streetHref && b.streetHref && a.streetHref === b.streetHref) ||
|
214 | (
|
215 |
|
216 | isStreetNameMatch(a.street, b.street) &&
|
217 | (
|
218 | (a.city && b.city && a.city.toLowerCase() === b.city.toLowerCase())|
|
219 | (a.zipCode === b.zipCode && isSameSubcity(a, b))
|
220 | )
|
221 | );
|
222 | return x;
|
223 | };
|
224 |
|
225 | module.exports = {
|
226 | printAddress: printAddress,
|
227 | isSameHouseNumberAndMailbox: isSameHouseNumberAndMailbox,
|
228 | isSameStreet: isSameStreet,
|
229 | isStreetNameMatch: isStreetNameMatch,
|
230 | addSubCityHref: addSubCityHref,
|
231 | addStreetHref: addStreetHref
|
232 | };
|