@servicetitan/acquisition-functions 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -5
- package/dist/__tests__/assessorlastsaledate-converter.test.js +7 -1
- package/dist/__tests__/filter-fetcher.test.js +8 -1
- package/dist/__tests__/property-fix-use-group.test.js +7 -1
- package/dist/__tests__/setup.js +6 -0
- package/dist/filter-fetcher/index.js +38 -45
- package/dist/fix-property-use/index.js +21 -17
- package/dist/property-assessorlastsaledate-converter/index.js +27 -23
- package/dist/zip-processor.js +43 -15
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ const setup_1 = require("./setup");
|
|
|
6
6
|
describe('property-assessorlastsaledate-converter', () => {
|
|
7
7
|
let processor;
|
|
8
8
|
let base;
|
|
9
|
+
let metadata;
|
|
9
10
|
(0, globals_1.beforeAll)(async () => {
|
|
10
11
|
const client = await (0, setup_1.openConnection)();
|
|
11
12
|
base = client.db('test');
|
|
@@ -18,7 +19,7 @@ describe('property-assessorlastsaledate-converter', () => {
|
|
|
18
19
|
mongoDb: base,
|
|
19
20
|
});
|
|
20
21
|
const { assessorLastSaleDateProcessor } = processor;
|
|
21
|
-
await assessorLastSaleDateProcessor.start('90001');
|
|
22
|
+
metadata = await assessorLastSaleDateProcessor.start('90001');
|
|
22
23
|
});
|
|
23
24
|
(0, globals_1.test)('should convert existing field to date', async () => {
|
|
24
25
|
const result = await new Promise(resolve => {
|
|
@@ -46,6 +47,11 @@ describe('property-assessorlastsaledate-converter', () => {
|
|
|
46
47
|
});
|
|
47
48
|
(0, globals_1.expect)(result[0].assessorlastsaledate).toBe(null);
|
|
48
49
|
});
|
|
50
|
+
(0, globals_1.test)('should return metadata', async () => {
|
|
51
|
+
(0, globals_1.expect)(metadata.errors).toBe(0);
|
|
52
|
+
(0, globals_1.expect)(metadata.properties).toBe(1);
|
|
53
|
+
(0, globals_1.expect)(metadata.requests).toBe(2);
|
|
54
|
+
});
|
|
49
55
|
});
|
|
50
56
|
describe('aggregate', () => {
|
|
51
57
|
(0, globals_1.beforeEach)(async () => {
|
|
@@ -6,6 +6,7 @@ const setup_1 = require("./setup");
|
|
|
6
6
|
describe('property-assessorlastsaledate-converter', () => {
|
|
7
7
|
let processor;
|
|
8
8
|
let base;
|
|
9
|
+
let metadata;
|
|
9
10
|
(0, globals_1.beforeAll)(async () => {
|
|
10
11
|
const client = await (0, setup_1.openConnection)();
|
|
11
12
|
base = client.db('test');
|
|
@@ -16,7 +17,7 @@ describe('property-assessorlastsaledate-converter', () => {
|
|
|
16
17
|
});
|
|
17
18
|
const { filterFetcher, propertyUseGroupProcessor } = processor;
|
|
18
19
|
await propertyUseGroupProcessor.start('90001');
|
|
19
|
-
await filterFetcher.start('90001
|
|
20
|
+
metadata = await filterFetcher.start(['90001', '90002']);
|
|
20
21
|
});
|
|
21
22
|
(0, globals_1.test)('should have empty filter for missing zip', async () => {
|
|
22
23
|
const result = await base.collection('filters').findOne({
|
|
@@ -30,6 +31,12 @@ describe('property-assessorlastsaledate-converter', () => {
|
|
|
30
31
|
(0, globals_1.expect)(result?.propertyusestandardized.length).toBe(0);
|
|
31
32
|
(0, globals_1.expect)(result?.utilitieswatersource.length).toBe(0);
|
|
32
33
|
});
|
|
34
|
+
(0, globals_1.test)('should return metadata', async () => {
|
|
35
|
+
(0, globals_1.expect)(metadata.errors).toBe(0);
|
|
36
|
+
(0, globals_1.expect)(metadata.properties).toBe(2);
|
|
37
|
+
(0, globals_1.expect)(metadata.requests).toBe(6);
|
|
38
|
+
(0, globals_1.expect)(metadata.filters).toBe(2);
|
|
39
|
+
});
|
|
33
40
|
(0, globals_1.test)('should form correct filter', async () => {
|
|
34
41
|
const result = await base.collection('filters').findOne({
|
|
35
42
|
zipcode: '90001',
|
|
@@ -11,6 +11,7 @@ describe('property-use-group-converter', () => {
|
|
|
11
11
|
});
|
|
12
12
|
describe('processor', () => {
|
|
13
13
|
let processor;
|
|
14
|
+
let metadata;
|
|
14
15
|
(0, globals_1.beforeAll)(async () => {
|
|
15
16
|
await (0, setup_1.setupProperties)(base);
|
|
16
17
|
processor = (0, index_1.configureProcessor)({
|
|
@@ -18,7 +19,12 @@ describe('property-use-group-converter', () => {
|
|
|
18
19
|
mongoDb: base,
|
|
19
20
|
});
|
|
20
21
|
const { propertyUseGroupProcessor } = processor;
|
|
21
|
-
await propertyUseGroupProcessor.start('90001
|
|
22
|
+
metadata = await propertyUseGroupProcessor.start('90001');
|
|
23
|
+
});
|
|
24
|
+
(0, globals_1.test)('should return metadata', async () => {
|
|
25
|
+
(0, globals_1.expect)(metadata.errors).toBe(0);
|
|
26
|
+
(0, globals_1.expect)(metadata.properties).toBe(2);
|
|
27
|
+
(0, globals_1.expect)(metadata.requests).toBe(2);
|
|
22
28
|
});
|
|
23
29
|
(0, globals_1.test)('should convert existing field to captial-case', async () => {
|
|
24
30
|
const result = await new Promise(resolve => {
|
package/dist/__tests__/setup.js
CHANGED
|
@@ -10,6 +10,12 @@ async function setupProperties(base) {
|
|
|
10
10
|
catch (e) {
|
|
11
11
|
// ignore
|
|
12
12
|
}
|
|
13
|
+
try {
|
|
14
|
+
await base.dropCollection('filters');
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
// ignore
|
|
18
|
+
}
|
|
13
19
|
try {
|
|
14
20
|
await base.createCollection('properties');
|
|
15
21
|
await base.collection('properties').insertMany(mock_1.MOCK);
|
|
@@ -11,74 +11,67 @@ function getFilterFetcherProcessor(db) {
|
|
|
11
11
|
};
|
|
12
12
|
const getProperties = async (zip) => {
|
|
13
13
|
const collection = await getPropertiesCollection();
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.toArray((err, results) => {
|
|
29
|
-
if (err) {
|
|
30
|
-
return reject(err);
|
|
31
|
-
}
|
|
32
|
-
resolve(results);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
14
|
+
return collection
|
|
15
|
+
.find({ zipcode: zip }, {
|
|
16
|
+
projection: {
|
|
17
|
+
zipcode: 1,
|
|
18
|
+
propertyusegroup: 1,
|
|
19
|
+
propertyusestandardized: 1,
|
|
20
|
+
hvaccoolingdetail: 1,
|
|
21
|
+
hvacheatingdetail: 1,
|
|
22
|
+
utilitieswatersource: 1,
|
|
23
|
+
flooringmaterialprimary: 1,
|
|
24
|
+
_id: 0, // eslint-disable-line
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
.toArray();
|
|
35
28
|
};
|
|
36
29
|
const deleteZipFilter = async (zip) => {
|
|
37
30
|
const collection = await getFiltersCollection();
|
|
38
|
-
return
|
|
39
|
-
collection.deleteOne({ zipcode: zip }, (err, results) => {
|
|
40
|
-
if (err) {
|
|
41
|
-
return reject(err);
|
|
42
|
-
}
|
|
43
|
-
resolve(results);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
31
|
+
return collection.deleteOne({ zipcode: zip });
|
|
46
32
|
};
|
|
47
33
|
const addZipFilters = async ({ zip, propertyusegroupCounts, propertyusestandardizedCounts, hvaccoolingdetailCounts, hvacheatingdetailCounts, utilitieswatersourceCounts, flooringmaterialprimaryCounts, }) => {
|
|
48
34
|
const collection = await getFiltersCollection();
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
flooringmaterialprimary: flooringmaterialprimaryCounts,
|
|
58
|
-
}, (err, results) => {
|
|
59
|
-
if (err) {
|
|
60
|
-
return reject(err);
|
|
61
|
-
}
|
|
62
|
-
resolve(results);
|
|
63
|
-
});
|
|
35
|
+
return collection.insertOne({
|
|
36
|
+
zipcode: zip,
|
|
37
|
+
propertyusegroup: propertyusegroupCounts,
|
|
38
|
+
propertyusestandardized: propertyusestandardizedCounts,
|
|
39
|
+
hvaccoolingdetail: hvaccoolingdetailCounts,
|
|
40
|
+
hvacheatingdetail: hvacheatingdetailCounts,
|
|
41
|
+
utilitieswatersource: utilitieswatersourceCounts,
|
|
42
|
+
flooringmaterialprimary: flooringmaterialprimaryCounts,
|
|
64
43
|
});
|
|
65
44
|
};
|
|
66
45
|
return async function processZip(zip, errors) {
|
|
46
|
+
const meta = {
|
|
47
|
+
requests: 0,
|
|
48
|
+
errors: 0,
|
|
49
|
+
properties: 0,
|
|
50
|
+
filters: 0,
|
|
51
|
+
};
|
|
67
52
|
if (!zip) {
|
|
68
|
-
return;
|
|
53
|
+
return meta;
|
|
69
54
|
}
|
|
70
55
|
try {
|
|
71
56
|
const properties = await getProperties(zip);
|
|
57
|
+
meta.requests += 1;
|
|
58
|
+
meta.properties += properties.length;
|
|
72
59
|
const filters = (0, calc_filter_count_1.calculateFilterCount)(properties);
|
|
73
60
|
await deleteZipFilter(zip);
|
|
61
|
+
meta.requests += 1;
|
|
74
62
|
await addZipFilters({
|
|
75
63
|
zip,
|
|
76
64
|
...filters,
|
|
77
65
|
});
|
|
66
|
+
meta.filters += 1;
|
|
67
|
+
meta.requests += 1;
|
|
78
68
|
}
|
|
79
69
|
catch (e) {
|
|
70
|
+
console.error(e);
|
|
80
71
|
errors.add(zip);
|
|
72
|
+
meta.errors += 1;
|
|
81
73
|
}
|
|
74
|
+
return meta;
|
|
82
75
|
};
|
|
83
76
|
}
|
|
84
77
|
exports.getFilterFetcherProcessor = getFilterFetcherProcessor;
|
|
@@ -11,20 +11,13 @@ function fixPropertyName(propertyName) {
|
|
|
11
11
|
function getPropertyUseGroupProcessor(db) {
|
|
12
12
|
const getProperties = async (zip) => {
|
|
13
13
|
const collection = await getPropertiesCollection(db);
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.toArray((err, results) => {
|
|
22
|
-
if (err) {
|
|
23
|
-
return reject(err);
|
|
24
|
-
}
|
|
25
|
-
resolve(results);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
14
|
+
return collection
|
|
15
|
+
.find({ zipcode: zip }, {
|
|
16
|
+
projection: {
|
|
17
|
+
propertyusegroup: 1,
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
.toArray();
|
|
28
21
|
};
|
|
29
22
|
function fixPropertyNames(properties) {
|
|
30
23
|
return properties
|
|
@@ -50,23 +43,34 @@ function getPropertyUseGroupProcessor(db) {
|
|
|
50
43
|
return collection.bulkWrite(propQuery, { ordered: true, w: 1 });
|
|
51
44
|
};
|
|
52
45
|
return async function processZip(zip, errors) {
|
|
46
|
+
const meta = {
|
|
47
|
+
requests: 0,
|
|
48
|
+
errors: 0,
|
|
49
|
+
properties: 0,
|
|
50
|
+
};
|
|
53
51
|
if (!zip) {
|
|
54
|
-
return;
|
|
52
|
+
return meta;
|
|
55
53
|
}
|
|
56
54
|
try {
|
|
57
55
|
const properties = await getProperties(zip);
|
|
56
|
+
meta.requests += 1;
|
|
58
57
|
if (!properties || !properties.length) {
|
|
59
|
-
return;
|
|
58
|
+
return meta;
|
|
60
59
|
}
|
|
61
60
|
const convertedProperties = fixPropertyNames(properties);
|
|
62
61
|
if (!convertedProperties.length) {
|
|
63
|
-
return;
|
|
62
|
+
return meta;
|
|
64
63
|
}
|
|
65
64
|
await updateProperties(convertedProperties);
|
|
65
|
+
meta.properties += convertedProperties.length;
|
|
66
|
+
meta.requests += 1;
|
|
66
67
|
}
|
|
67
68
|
catch (e) {
|
|
69
|
+
console.error(e);
|
|
68
70
|
errors.add(zip);
|
|
71
|
+
meta.errors += 1;
|
|
69
72
|
}
|
|
73
|
+
return meta;
|
|
70
74
|
};
|
|
71
75
|
}
|
|
72
76
|
exports.getPropertyUseGroupProcessor = getPropertyUseGroupProcessor;
|
|
@@ -8,26 +8,19 @@ const getPropertiesCollection = async (db) => {
|
|
|
8
8
|
function getAssessorLastSaleDateProcessor(db) {
|
|
9
9
|
const getPropertiesAssessorLastSaleDate = async (zip) => {
|
|
10
10
|
const collection = await getPropertiesCollection(db);
|
|
11
|
-
return
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
.toArray((err, results) => {
|
|
25
|
-
if (err) {
|
|
26
|
-
return reject(err);
|
|
27
|
-
}
|
|
28
|
-
resolve(results);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
11
|
+
return collection
|
|
12
|
+
.find({
|
|
13
|
+
zipcode: zip,
|
|
14
|
+
assessorlastsaledate: {
|
|
15
|
+
$exists: true,
|
|
16
|
+
$type: 2,
|
|
17
|
+
},
|
|
18
|
+
}, {
|
|
19
|
+
projection: {
|
|
20
|
+
assessorlastsaledate: 1,
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
.toArray();
|
|
31
24
|
};
|
|
32
25
|
const updateProperties = async (properties) => {
|
|
33
26
|
const collection = await getPropertiesCollection(db);
|
|
@@ -41,23 +34,34 @@ function getAssessorLastSaleDateProcessor(db) {
|
|
|
41
34
|
return collection.bulkWrite(propQuery, { ordered: true, w: 1 });
|
|
42
35
|
};
|
|
43
36
|
return async function processZip(zip, errors) {
|
|
37
|
+
const meta = {
|
|
38
|
+
requests: 0,
|
|
39
|
+
errors: 0,
|
|
40
|
+
properties: 0,
|
|
41
|
+
};
|
|
44
42
|
if (!zip) {
|
|
45
|
-
return;
|
|
43
|
+
return meta;
|
|
46
44
|
}
|
|
47
45
|
try {
|
|
48
46
|
const properties = await getPropertiesAssessorLastSaleDate(zip);
|
|
47
|
+
meta.requests += 1;
|
|
49
48
|
if (!properties || !properties.length) {
|
|
50
|
-
return;
|
|
49
|
+
return meta;
|
|
51
50
|
}
|
|
52
51
|
const convertedProperties = (0, utils_1.convertStringToDate)(properties, 'assessorlastsaledate');
|
|
53
52
|
if (!convertedProperties.length) {
|
|
54
|
-
return;
|
|
53
|
+
return meta;
|
|
55
54
|
}
|
|
56
55
|
await updateProperties(convertedProperties);
|
|
56
|
+
meta.properties += convertedProperties.length;
|
|
57
|
+
meta.requests += 1;
|
|
57
58
|
}
|
|
58
59
|
catch (e) {
|
|
60
|
+
console.error(e);
|
|
61
|
+
meta.errors += 1;
|
|
59
62
|
errors.add(zip);
|
|
60
63
|
}
|
|
64
|
+
return meta;
|
|
61
65
|
};
|
|
62
66
|
}
|
|
63
67
|
exports.getAssessorLastSaleDateProcessor = getAssessorLastSaleDateProcessor;
|
package/dist/zip-processor.js
CHANGED
|
@@ -10,19 +10,25 @@ function zipProcessor(config, processorFn) {
|
|
|
10
10
|
if (!zips) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
endZipNum
|
|
17
|
-
|
|
18
|
-
for (let zipNum = startZipNum; zipNum <= endZipNum;) {
|
|
19
|
-
const processes = [];
|
|
20
|
-
const processZipEnd = zipNum + config.workers - 1;
|
|
21
|
-
for (; zipNum <= endZipNum && zipNum <= processZipEnd; zipNum++) {
|
|
22
|
-
const zip = (0, utils_1.convertToZipString)(zipNum);
|
|
23
|
-
processes.push(processorFn(zip, erroredZips));
|
|
13
|
+
if (Array.isArray(zips)) {
|
|
14
|
+
// eslint-disable-next-line prefer-const
|
|
15
|
+
let [startZipNum, endZipNum] = zips.map(Number);
|
|
16
|
+
if (!endZipNum) {
|
|
17
|
+
endZipNum = startZipNum;
|
|
24
18
|
}
|
|
25
|
-
|
|
19
|
+
for (let zipNum = startZipNum; zipNum <= endZipNum;) {
|
|
20
|
+
const processes = [];
|
|
21
|
+
const processZipEnd = zipNum + config.workers - 1;
|
|
22
|
+
for (; zipNum <= endZipNum && zipNum <= processZipEnd; zipNum++) {
|
|
23
|
+
const zip = (0, utils_1.convertToZipString)(zipNum);
|
|
24
|
+
processes.push(processorFn(zip, erroredZips));
|
|
25
|
+
}
|
|
26
|
+
yield await Promise.all(processes);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const zip = (0, utils_1.convertToZipString)(Number(zips));
|
|
31
|
+
yield await processorFn(zip, erroredZips);
|
|
26
32
|
}
|
|
27
33
|
while (erroredZips.size) {
|
|
28
34
|
const connectionErrorZipsInner = [...erroredZips];
|
|
@@ -39,17 +45,39 @@ function zipProcessor(config, processorFn) {
|
|
|
39
45
|
}
|
|
40
46
|
processor = null;
|
|
41
47
|
}
|
|
48
|
+
const meta = {
|
|
49
|
+
requests: 0,
|
|
50
|
+
properties: 0,
|
|
51
|
+
errors: 0,
|
|
52
|
+
filters: 0,
|
|
53
|
+
};
|
|
54
|
+
function sumMetas(metas) {
|
|
55
|
+
if (!metas) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
return (Array.isArray(metas) ? metas : [metas]).forEach(m => {
|
|
59
|
+
meta.requests += m.requests;
|
|
60
|
+
meta.properties += m.properties;
|
|
61
|
+
meta.errors += m.errors;
|
|
62
|
+
if (m.filters) {
|
|
63
|
+
meta.filters += m.filters;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
42
67
|
async function start(zips) {
|
|
43
68
|
processor = processZips(zips);
|
|
44
69
|
try {
|
|
45
|
-
let
|
|
46
|
-
while (processor && !
|
|
47
|
-
step = await processor.next();
|
|
70
|
+
let isDone = false;
|
|
71
|
+
while (processor && !isDone) {
|
|
72
|
+
const step = await processor.next();
|
|
73
|
+
sumMetas(step.value);
|
|
74
|
+
isDone = Boolean(step.done);
|
|
48
75
|
}
|
|
49
76
|
}
|
|
50
77
|
catch (e) {
|
|
51
78
|
await clear();
|
|
52
79
|
}
|
|
80
|
+
return meta;
|
|
53
81
|
}
|
|
54
82
|
return {
|
|
55
83
|
getProcessor: () => processor,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/acquisition-functions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"typings": "./dist/index.d.ts",
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"cli": {
|
|
29
29
|
"webpack": false
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "7c93d00316dcd4bd83e1a42720579ed22c6ce208"
|
|
32
32
|
}
|