-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdata-processor.js
More file actions
306 lines (280 loc) · 11.1 KB
/
Copy pathdata-processor.js
File metadata and controls
306 lines (280 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
const csv = require('csv-parser')
var curry = require('curry');
const ObjectsToCsv = require('objects-to-csv');
const fs = require('fs')
const results = [];
const config = require('minimist')(process.argv).config.split(',');
const command = config[0]
const fileToUse = config[1]
/*
test
matches =
[
UPC(0),
Description(3),
Default cost Average Unit Cost(10),
Price(11),
Category(14),
Sub Category(15),
Sub Category 2 (16),
Vendor(19),
Matrix Group Color(24),
Matrix Group Size(25)
]
*/
const storesStart = 27;
const storesLength = 15;
const newSkuLocation = 2;
const defaultCostLocation = 10;
const skuLocation = 1;
const matches = [0, 3, 11, 14, 15, 16, 19, 24, 25];
fs.createReadStream(fileToUse)
.pipe(csv())
.on('data', (data) => results.push(data))
.on('end', () => {
if(command == "testFor3") testForThree(results)
else if(command == "process") processResults(results)
else if(command == "people") handleDuplicateNames(results)
});
function testForThree(_results){
/*
returns info on groups that match for 3 or more
*/
const startTime = new Date().toLocaleTimeString();
let largeGroups = 0;
let groupedObjects = []
while(_results.length){
//remove first value from _results
let row = _results.pop();
let rowData = objectValues(row);
let groupedData = [];
//filter results and keep non matched and pull matched
_results = _results.filter(searchRow =>{
let isMatch = true;
//get data from current row
let compareRowData = objectValues(searchRow);
//loop for the matches array length to see if everything matches
for(let i = 0; i < matches.length; i++){
//if anyone doesnt match set isMatch to false
if(compareRowData[matches[i]].toLowerCase() != rowData[matches[i]].toLowerCase()){
isMatch = false;
}
}
//EXIT LOOPING FOR MATCHES
//if we have a match add it to a container that will hold all matches, and return false so it doesnt stay in results array
if(isMatch){
groupedData.push(searchRow);
return false;
}else{
return true;
}
})//EXIT FILTER
//if we have a match of 3 or more, display information about them and push to grouped objects so we can make csv
if(groupedData.length >= 2){
groupedData.push(row);
largeGroups ++;
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("WE FOUND A MATCH OF " + (groupedData.length + 1))
console.log("UPC", getObjectValue(row, 0))
console.log("Custom Skus", getGroupedValues(groupedData, skuLocation))
console.log("Vendor", getObjectValue(row, 19))
console.log("Category", getObjectValue(row, 14))
const infoObject = {
matchSize: (groupedData.length),
UPC: getObjectValue(row, 0),
CustomSkus: getGroupedValues(groupedData, skuLocation),
Vendor: getObjectValue(row, 19),
Category: getObjectValue(row, 14)
}
groupedObjects.push(infoObject)
}
}//EXIT WHILE
new ObjectsToCsv(groupedObjects).toDisk('./output/testForThree.csv');
console.log("FOUND MATCHES:::: " + largeGroups)
console.log("FINISHED " + "Started at- " + startTime + ' ENDED AT- ' + new Date().toLocaleTimeString())
}
function processResults(_results){
/*
find rows that match all items in the matched array
update store count and sku for matched items
return csv file with updated matching rows
*/
let newResults = [];
let total = _results.length;
const startTime = new Date().toLocaleTimeString();
while(_results.length){
//remove first value from _results
let row = _results.pop();
let rowData = objectValues(row);
let groupedData = [];
//filter results and keep non matched and pull matched
_results = _results.filter(searchRow =>{
let isMatch = true;
//get data from current row
let compareRowData = objectValues(searchRow);
//loop for the matches array length to see if everything matches
for(let i = 0; i < matches.length; i++){
//if anyone doesnt match set isMatch to false
if(compareRowData[matches[i]].toLowerCase() != rowData[matches[i]].toLowerCase()){
isMatch = false;
}
}
//EXIT LOOPING FOR MATCHES
//if we have a match add it to a container that will hold all matches, and return false so it doesnt stay in results array
if(isMatch){
groupedData.push(searchRow);
return false;
}else{
return true;
}
})//EXIT FILTER
//single entry gets added to new results
if(groupedData.length == 0){
newResults.push(row);
}
//if we have grouped data, make a new row with data combined, then add to new results
else{
console.log('we had a match!', groupedData.length)
if(groupedData.length >= 3){
let testVal = groupedData[1]
console.log('problem')
}
//put copied sku in the default row in the new sku location
let copiedRowSku = getObjectValue(groupedData[0], skuLocation);
let setValueInRow = setObjValue(row);
row = setValueInRow(copiedRowSku)(newSkuLocation);
//update store quantity values
//loop for each store
for(let i = 0; i <= storesLength; i++ ){
//get current store position
let currentStore = storesStart + i;
//get value from copied row at that store, and from the default row
let copiedStoreValue = getObjectValueAsInt(groupedData[0], currentStore);
let defaultStoreValue = getObjectValueAsInt(row, currentStore);
//add new value to the default row store
let storeValueSum = copiedStoreValue + defaultStoreValue;
row = setValueInRow(storeValueSum)(currentStore);
}
//check if default cost is differnet, if so use the largest number
let copiedDefaultCost = getObjectValueAsInt(groupedData[0], defaultCostLocation);
let defaultCost = getObjectValueAsInt(row, defaultCostLocation);
let newDefaultCost = copiedDefaultCost >= defaultCost ? copiedDefaultCost : defaultCost
row = setValueInRow(newDefaultCost)(defaultCostLocation);
newResults.push(row);
}
console.log(_results.length + ' remaining from: ' + total);
}//EXIT WHILE
//convert newResults object to a csv file
new ObjectsToCsv(newResults).toDisk('./output/processResults.csv');
console.log("FINISHED " + "Started at- " + startTime + ' ENDED AT- ' + new Date().toLocaleTimeString())
}
function handleDuplicateNames(_results){
/*
get all rows with the same first/last name
merge rows.
if a cell had a value, use current value or next available value if there are any in the compared rows
*/
let newResults = [];
let total = _results.length;
const startTime = new Date().toLocaleTimeString();
const startSize = _results.length;
let isDupe = 0;
while(_results.length){
//remove first value from _results
let row = _results.pop();
let rowData = objectValues(row);
let groupedData = [];
//filter results and keep non matched and pull matched
_results = _results.filter(searchRow =>{
let isMatch = false;
//get data from current row
let compareRowData = objectValues(searchRow);
//get a match of first and last name
if(rowData[1].toLowerCase() == compareRowData[1].toLowerCase() && rowData[2].toLowerCase() == compareRowData[2].toLowerCase() ){
isMatch = true;
}
//if we have a match add it to a container that will hold all matches, and return false so it doesnt stay in results array
if(isMatch){
groupedData.push(searchRow);
return false;
}else{
return true;
}
})//EXIT FILTER LOOKING FOR MATCHES
//single entry gets added to new results
if(groupedData.length == 0){
newResults.push(row);
}
//if we have grouped data, make a new row with data combined, then add to new results
else{
console.log('we had a match!', groupedData.length)
isDupe ++;
Object.keys(row).map((key,index) => {//loop keys in the row that was matched and look at every value
let val = row[key];//grab a value
let updatedVal = '';//prepare for an updated value
if(!val){//if there is no initial value, check the other rows for a value
//reduce groupedData to look at all matching rows and finding what their value is for that cell
val = groupedData.reduce((_acc,_val,_index)=>{//loop through other rows
if(_acc) return _acc;//if we set a value, just keep it and dont care what the rest of the values are.
const compareRowVal = _val[key] //get current key value from row
if(compareRowVal){ //check if it has a value, if so then set it to the accum and return
_acc = compareRowVal ? compareRowVal : '';
return _acc;
}
},'')
}
return setObjValue(row, val, index)//set our row data to the updated data
});
newResults.push(row);//add row to the list
}
console.log(_results.length + ' remaining from: ' + total);
}//EXIT WHILE
//convert newResults object to a csv file
console.log("OLD SIZE:",startSize, "NEW SIZE:", newResults.length, "TOTAL DUPLICATED:",isDupe )
new ObjectsToCsv(newResults).toDisk('./output/handleDuplicateNames.csv');
console.log("FINISHED " + "Started at- " + startTime + ' ENDED AT- ' + new Date().toLocaleTimeString())
}
function objectValues(_obj){
return Object.keys(_obj).map((key,index) => {
return _obj[key];
});
}
var setObjValue = curry((_obj,_val,_location) =>{
Object.keys(_obj).map((key,index) =>{
if(index == _location){
_obj[key] = _val;
}
})
return _obj;
})
function setObjectValue(_obj,_val,_location){
Object.keys(_obj).map((key,index) =>{
if(index == _location){
_obj[key] = _val;
}
})
return _obj;
}
function getObjectValue(_obj,_valueLocation){
let val = null;
Object.keys(_obj).map((key,index) =>{
if(index == _valueLocation){
val = _obj[key];
}
});
return val;
}
function getObjectValueAsInt(_obj, _valLocation){
let val = parseFloat(getObjectValue(_obj, _valLocation));
return isNaN(val) ? 0 : val;
}
function getGroupedValues(_rows, _valueLocation){
//gets array of same objects and combines values into a comma seperated string
let val = _rows.reduce((acc,item)=>{
acc += getObjectValue(item, _valueLocation) + ', ';
return acc
},'')
//remove last comma
val = val.replace(/,\s*$/, "")
return val;
}