Subversion Repositories munaweb

Rev

Rev 15 | Rev 19 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
<!DOCTYPE html>
2
<html lang="en">
3
 
4
<head>
5
    <title>eBay Listings Price Check</title>
6
    <meta charset="UTF-8">
7
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
9
    <link rel="icon" href="favicon.ico" type="image/x-icon">
10
 
11
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
12
    <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
13
    <link rel="stylesheet" href="css/style.css">
14
    <script src="js/XMLWriter.js"></script>
15
    <script src="js/lodash.min.js"></script>
16
    <script src="js/muna-tools.js"></script>
17
</head>
18
 
19
<body onload="return initConfig();">
20
    <div class="w3-main">
21
        <div class="w3-container w3-padding w3-margin w3-card-4">
22
            <div class="w3-container w3-gray" style="height:100px">
23
                <img class="w3-image" src="images/MUNA%20-%20Logo%20100x100.png" alt="MUNA Trading Logo" style="height:100px">
24
                <p id="connected" class="w3-xxlarge w3-right">eBay Listings Price Check
25
                    <input id="login" type="button" class="w3-btn w3-large w3-green w3-margin w3-round-large w3-ripple w3-right w3-hide" onclick="eBayLogin();" value="Login" />
26
                </p>
27
            </div>
28
 
29
            <div class="w3-row">
30
                <div>
31
                    <form id="searchForm" class="w3-container w3-light-grey w3-padding w3-small" onsubmit="return checkListingPrices();">
32
                        <div class="w3-container w3-card-2 w3-cell w3-padding">
33
                            <input id="startButton" type="button" class="w3-btn w3-large w3-black w3-margin w3-round-large w3-ripple w3-right" onclick="checkListingPrices();" value="Start" />
34
                        </div>
35
                    </form>
36
                </div>
37
                <div id="progressBarDiv" class="w3-container w3-padding w3-margin w3-card-4 w3-hide">
38
                    <h2 id="progressBarHeader"></h2>
39
                    <div class="w3-light-grey">
40
                        <div id="progressBar" class="w3-container w3-green w3-center" style="width:0%">0%</div>
41
                    </div>
42
                </div>
43
                <div id="results" class="w3-container w3-padding w3-card-4 w3-hide"></div>
44
                <div id="logging" class="w3-container w3-padding"></div>
45
            </div>
46
        </div>
47
 
48
        <footer class="w3-container w3-center w3-border-top w3-margin">
17 - 49
            <div w3-include-html="php/footer.php"></div>
2 - 50
        </footer>
51
 
52
    </div>
6 - 53
 
2 - 54
    <script>
55
 
56
// Config
57
var configMinPrice = "5.99";
58
var configDifference = 2.00;
59
var configPercentage = 20.00;
60
var configAbsoluteMinPrice = 5.00;
61
var configAdjMinPrice = 5.48;
62
var configSearchUrl = 'https://ujsoftware.linkpc.net/ebay/search.html?keyword=';
63
var configSearchUrlPart2 = '&hideDuplicateItems=on&locatedIn=WorldWide&sortOrder=PricePlusShippingLowest&results=100';
64
 
65
var pagesToProcess = 0;
66
var maxPagesToProcess = 0;
67
var pagesProcessed = 0;
68
var productIdsToProcess = 0;
69
var maxProductIdsToProcess = 0;
70
var productIdsProcessed = 0;
71
var productsToPrice = 0;
72
var maxProductsToPrice = 0;
73
var productsPriced = 0;
74
var html = [];
75
 
76
// Initialize Configuration Variables
77
function initConfig() {
78
    eBayAuthToken = readCookie();
79
    if (eBayAuthToken.length > 0) {
80
        connected();
81
    }
82
 
83
    if (eBayAuthTokenFlag === false) {
84
        var x = document.getElementById("login");
85
        if (x.className.indexOf("w3-show") == -1) {
86
            x.className += " w3-show";
87
        }
88
    }
89
}
90
 
91
function requireNewLogin() {
92
    // dummy
93
}
94
 
95
function checkListingPrices() {
96
    var x;
97
 
98
    document.getElementById("logging").innerHTML = '';
99
 
100
    x = document.getElementById("results");
101
    if (x.className.indexOf("w3-show") == -1) {
102
        x.className += " w3-show";
103
    }
104
    x.className = x.className.replace(" process-errors", "");
105
    x.innerHTML = '';
106
 
107
    initProgressBar('Retrieving Active Listings (1/3)');
108
 
109
    pagesToProcess = 1;
110
    maxPagesToProcess = 1;
111
    pagesProcessed = 0;
112
    eBaySearch(1);
113
 
114
    function checkpagesToProcess() {
115
        if (pagesToProcess > 0) {
116
            window.setTimeout(checkpagesToProcess, 100); // wait 100 milliseconds
117
        } else {
118
            findMissingProductIds();
119
        }
120
    }
121
 
122
    checkpagesToProcess();
123
}
124
 
125
// item filters for request
126
var filterarray = [];
127
var urlfilter = [];
128
 
129
// Fill the array of item filters from input form
130
function fillFilterArray() {
131
    filterarray = [];
132
    var obj = [];
133
 
134
    obj = {
135
        "name": "Seller",
136
        "value": configeBaySellerName,
137
        "paramName": "",
138
        "paramValue": ""
139
    };
140
    filterarray.push(obj);
141
 
142
    obj = {
143
        "name": "MinPrice",
144
        "value": Number(configMinPrice).toFixed(2),
145
        "paramName": "Currency",
146
        "paramValue": "USD"
147
    };
148
    filterarray.push(obj);
149
 
150
    obj = {
151
        "name": "ListingType",
152
        "value": "FixedPrice",
153
        "paramName": "",
154
        "paramValue": ""
155
    };
156
    filterarray.push(obj);
157
 
158
    urlfilter = "";
159
    // Iterate through each filter in the array
160
    for (var i = 0; i < filterarray.length; i++) {
161
        //Index each item filter in filterarray
162
        var itemfilter = filterarray[i];
163
        // Iterate through each parameter in each item filter
164
        for (var index in itemfilter) {
165
            // Check to see if the paramter has a value (some don't)
166
            if (itemfilter[index] !== "") {
167
                if (itemfilter[index] instanceof Array) {
168
                    for (var r = 0; r < itemfilter[index].length; r++) {
169
                        var value = itemfilter[index][r];
170
                        urlfilter += "&itemFilter\(" + i + "\)." + index + "\(" + r + "\)=" + value;
171
                    }
172
                } else {
173
                    urlfilter += "&itemFilter\(" + i + "\)." + index + "=" + itemfilter[index];
174
                }
175
            }
176
        }
177
    }
178
} // End fillFilterArray() function
179
 
180
var url = "";
181
 
182
function eBaySearch(pageNumber) {
183
    // Fill the filter array from form input
184
    if (pageNumber == 1) {
185
        fillFilterArray();
186
    }
187
 
188
    // Construct the request
189
    url = configeBayFinding + "?";
190
    url += "OPERATION-NAME=findItemsAdvanced";
191
    url += "&SERVICE-VERSION=" + configeBayFindingVersion;
192
    url += "&SECURITY-APPNAME=" + configAppid;
193
    url += "&GLOBAL-ID=EBAY-US";
194
    url += "&RESPONSE-DATA-FORMAT=JSON";
195
    url += "&REST-PAYLOAD";
196
    url += "&paginationInput.entriesPerPage=100";
197
    url += "&paginationInput.pageNumber=";
198
    url += pageNumber;
199
    url += urlfilter;
200
 
201
    var xhttp = new XMLHttpRequest();
202
 
203
    xhttp.onreadystatechange = function() {
204
        if (this.readyState == 4) {
205
            _cb_findItemsAdvanced(JSON.parse(this.responseText));
206
        }
207
    };
208
 
209
    xhttp.open("GET", configProxyUrl, true);
210
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
211
    xhttp.send();
212
 
213
    return false;
214
}
215
 
4 - 216
function printeBayAPIError(str, root) {
2 - 217
    var x = document.getElementById("results");
218
    x.className += " process-errors";
4 - 219
    x.innerHTML += "<h2>eBay API Error (" + str + ")<h2>";
2 - 220
    x.innerHTML += "<p>Id: " + root.errorMessage[0].error[0].errorId + "<br/>";
221
    x.innerHTML += "<p>Severity: " + root.errorMessage[0].error[0].severity + "<br/>";
222
    x.innerHTML += "<p>Message: " + root.errorMessage[0].error[0].message + "</p>";
223
}
224
 
225
// Parse the response and build an HTML table to display search results
226
function _cb_findItemsAdvanced(root) {
227
    // Error Handling
228
    var response = root.findItemsAdvancedResponse[0];
229
    var ack = response.ack;
230
    if (ack != 'Success') {
4 - 231
        printeBayAPIError('Find Item', response);
2 - 232
 
233
        if (ack == 'Failure' || ack == 'PartialFailure') {
234
            --pagesToProcess;
235
            return;
236
        }
237
    }
238
 
239
    createTable(response.searchResult[0].item || [], Number(response.paginationOutput[0].pageNumber), Number(response.paginationOutput[0].totalPages));
240
 
6 - 241
    if (Number(response.paginationOutput[0].totalPages) > Number(response.paginationOutput[0].pageNumber)) {
242
        ++maxPagesToProcess;
243
        ++pagesToProcess;
244
        eBaySearch(Number(response.paginationOutput[0].pageNumber) + 1);
245
    }
2 - 246
 
247
    document.getElementById("logging").innerHTML = html.join('');
248
    --pagesToProcess;
249
    ++pagesProcessed;
250
    updateProgressBar(maxPagesToProcess, pagesProcessed);
251
} // End _cb_findItemsAdvanced() function
252
 
253
 
254
function createTable(obj, pageNumber, totalPages) {
255
    if (pageNumber == 1) {
256
        document.getElementById("logging").innerHTML = '';
257
        html = [];
258
 
259
        html.push('<h3>Price Validation</h3>');
260
        html.push('<div class="w3-responsive">');
261
        html.push('<table id="itemTable" class="w3-table-all w3-hoverable css-serial">');
262
        html.push('<thead>');
263
        html.push('<tr>');
264
 
265
        html.push(tableHeader('#'));
266
        html.push(tableHeader('Item Id'));
267
        html.push(tableHeader('Thumbnail'));
268
        html.push(tableHeader('Title'));
269
        html.push(tableHeader('Product Id'));
270
        html.push(tableHeader('Price'));
271
        html.push(tableHeader('# Active Listings'));
272
        html.push(tableHeader('# Priced Lower'));
273
        html.push(tableHeader('Lowest Price'));
274
        html.push(tableHeader('Highest Price'));
275
        html.push(tableHeader('Above/Below Lowest'));
276
        html.push(tableHeader('Views'));
277
        html.push(tableHeader('Watchers'));
278
        html.push(tableHeaderHidden('Condition'));
279
        html.push(tableHeaderHidden('# Better Condition'));
280
        html.push(tableHeader('Price Adj.'));
281
        html.push(tableHeaderHidden('Best Offer'));
282
        html.push(tableHeaderHidden('MinBetterCondition'));
283
        html.push(tableHeaderHidden('BetterConditionBreakdown'));
284
        html.push(tableHeaderHidden('SameConditionBreakdown'));
285
 
286
        html.push('</tr>');
287
        html.push('</thead>');
288
        html.push('<tbody>');
289
    }
290
 
291
    for (var entry = 0; entry < obj.length; entry++) {
292
        html.push('<tr>');
293
        html.push(tableCell(''));
294
        html.push(tableCell('<a href="' + obj[entry].viewItemURL + '" target="_blank">' + obj[entry].itemId + '</a>'));
295
        html.push(tableCell('<img src="' + obj[entry].galleryURL[0].replace('http:', 'https:') + '">'));
296
        html.push(tableCell(obj[entry].title));
297
        if (obj[entry].productId !== undefined) {
298
            var str = '<a href="' + configSearchUrl;
299
            str += 'ReferenceID%3A' + obj[entry].productId[0].__value__;
300
            str += configSearchUrlPart2 + '" target="_blank">';
301
            str += obj[entry].productId[0]["@type"] + ' ' + obj[entry].productId[0].__value__;
302
            str += '</a>';
303
            html.push(tableCell(str));
304
        } else {
305
            html.push(tableCellLabel('ProductId' + obj[entry].itemId));
306
        }
307
 
308
        html.push(tableCell('$' + Number(obj[entry].sellingStatus[0].convertedCurrentPrice[0].__value__).toFixed(2)));
309
        html.push(tableCell(1));
310
        html.push(tableCell(0));
311
        html.push(tableCell('$0.00'));
312
        html.push(tableCell('$0.00'));
313
        html.push(tableCell('$0.00 (0.00%)'));
314
 
315
        html.push(tableCell(0));
316
        html.push(tableCell(obj[entry].listingInfo[0].watchCount === undefined ? 0 : Number(obj[entry].listingInfo[0].watchCount)));
317
        html.push(tableCellHidden(obj[entry].condition === undefined ? 4000 : Number(obj[entry].condition[0].conditionId)));
318
        html.push(tableCellHidden(0));
319
        html.push(tableCell('<input id="PriceAdj' + obj[entry].itemId + '" type="text" size="10"><br><input type="button" class="w3-btn w3-large w3-black w3-margin w3-round-large w3-ripple" onclick="changePrice(' + obj[entry].itemId + ');" value="Adjust Price" />'));
320
        html.push(tableCellLabelHidden('BestOffer' + obj[entry].itemId, obj[entry].listingInfo[0].bestOfferEnabled));
321
        html.push(tableCellHidden('0'));
322
        html.push(tableCellHidden('[]'));
323
        html.push(tableCellHidden('[]'));
324
 
325
        html.push('</tr>');
326
    }
327
 
328
    if (pageNumber == totalPages) {
329
        html.push('</tbody>');
330
        html.push('</table>');
331
        html.push('</div>');
332
    }
333
}
334
 
335
function setCellsAttribute(table, row, col, label) {
336
    table.rows[row].cells[col].setAttribute("id", label);
337
}
338
 
339
function sortTableDesc(tableName, column) {
340
    var table, rows, switching, i, x, y, shouldSwitch;
341
    --column; // column parameter starts with 1
342
    table = document.getElementById(tableName);
343
    switching = true;
344
    /*Make a loop that will continue until
345
    no switching has been done:*/
346
    while (switching) {
347
        //start by saying: no switching is done:
348
        switching = false;
349
        rows = table.getElementsByTagName("TR");
350
        /*Loop through all table rows (except the
351
        first, which contains table headers:*/
352
        for (i = 1; i < (rows.length - 1); i++) {
353
            //start by saying there should be no switching:
354
            shouldSwitch = false;
355
            /*Get the two elements you want to compare,
356
            one from current row and one from the next:*/
357
            x = rows[i].getElementsByTagName("TD")[column];
358
            y = rows[i + 1].getElementsByTagName("TD")[column];
359
            //check if the two rows should switch place:
360
            if (x !== undefined && (Number(x.innerHTML.substr(1)) < Number(y.innerHTML.substr(1)))) {
361
                //if so, mark as a switch and break the loop:
362
                shouldSwitch = true;
363
                break;
364
            }
365
        }
366
        if (shouldSwitch) {
367
            /*If a switch has been marked, make the switch
368
            and mark that a switch has been done:*/
369
            rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
370
            switching = true;
371
        }
372
    }
373
}
374
 
375
function findMissingProductIds() {
376
    var i;
377
    var x = document.getElementById("itemTable");
378
    var missingList = [];
379
    var viewList = [];
380
    var maxItems = 20;
381
 
382
    initProgressBar('Retrieving Product Ids (2/3)');
383
 
384
    productIdsToProcess = 0;
385
    maxProductIdsToProcess = 0;
386
    productIdsProcessed = 0;
387
 
388
    for (i = 1; i < x.rows.length; i++) {
389
        if (x.rows[i].cells[4] !== undefined && x.rows[i].cells[4].innerText.length < 1) {
390
            missingList.push(x.rows[i].cells[1].innerText);
391
        } else {
392
            var p = x.rows[i].cells[4].innerText.substr(x.rows[i].cells[4].innerText.indexOf(" ") + 1);
393
            setCellsAttribute(x, i, 5, "Price" + p);
394
            setCellsAttribute(x, i, 6, "Active" + p);
395
            setCellsAttribute(x, i, 7, "Lower" + p);
396
            setCellsAttribute(x, i, 8, "Minimum" + p);
397
            setCellsAttribute(x, i, 9, "Maximum" + p);
398
            setCellsAttribute(x, i, 11, "Views" + x.rows[i].cells[1].innerText);
399
            setCellsAttribute(x, i, 13, "Condition" + p);
400
            setCellsAttribute(x, i, 14, "BetterCondition" + p);
401
            setCellsAttribute(x, i, 17, "MinBetterCondition" + p);
402
            setCellsAttribute(x, i, 18, "BetterConditionBreakdown" + p);
403
            setCellsAttribute(x, i, 19, "SameConditionBreakdown" + p);
404
            viewList.push(x.rows[i].cells[1].innerText);
405
        }
406
    }
407
 
408
    for (i = 0;
409
        (i * maxItems) < missingList.length; i++) {
410
        ++productIdsToProcess;
411
        ++maxProductIdsToProcess;
412
        findMissingProductId(missingList.slice(i * maxItems, (i + 1) * maxItems));
413
    }
414
 
415
    for (i = 0;
416
        (i * maxItems) < viewList.length; i++) {
417
        ++productIdsToProcess;
418
        ++maxProductIdsToProcess;
419
        findViews(viewList.slice(i * maxItems, (i + 1) * maxItems));
420
    }
421
 
422
    function checkproductIdsToProcess() {
423
        if (productIdsToProcess > 0) {
424
            window.setTimeout(checkproductIdsToProcess, 100); // wait 100 milliseconds
425
        } else {
426
            priceProductIds();
427
        }
428
    }
429
 
430
    checkproductIdsToProcess();
431
}
432
 
433
function findMissingProductId(itemIdList) {
434
    var i;
435
    var xml;
436
 
437
    var xw = new XMLWriter('UTF-8', '1.0');
438
    var xhr = new XMLHttpRequest();
439
 
440
    xw.writeStartDocument();
441
    xw.writeStartElement("GetMultipleItemsRequest");
442
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
443
 
444
    for (i = 0; i < itemIdList.length; i++) {
445
        xw.writeElementString('ItemID', itemIdList[i]);
446
    }
447
 
448
    xw.writeElementString('IncludeSelector', 'Details');
449
    xw.writeElementString('ErrorLanguage', 'en_US');
450
    xw.writeElementString('Version', configeBayShoppingVersion);
451
    xw.writeElementString('WarningLevel', configWarningLevel);
452
 
453
    xw.writeEndElement(); /* xmlrequest */
454
    xw.writeEndDocument();
455
 
456
    xhr.open('POST', configProxyUrl, true);
457
    xhr.setRequestHeader('Content-Type', 'text/xml');
458
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
459
    xhr.setRequestHeader('X-EBAY-API-VERSION', configeBayShoppingVersion);
460
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', 'GetMultipleItems');
461
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
462
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
463
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
464
    xhr.setRequestHeader('X-EBAY-API-REQUEST-ENCODING', 'XML');
465
    xhr.setRequestHeader('X-Proxy-URL', configeBayShopping);
466
 
467
    xml = xw.flush();
468
    xw.close();
469
 
470
    xhr.onload = function() {
17 - 471
        var jsonObj = XMLparse(xhr.responseXML, false);
472
        var obj = jsonObj.GetMultipleItemsResponse;
2 - 473
        var returnCode = obj.Ack;
474
 
475
        var x = document.getElementById("results");
476
 
477
        if (returnCode == 'Success') {
478
            for (i = 0; i < obj.Item.length; i++) {
479
                var ItemID = getJsonValue(obj.Item[i].ItemID);
480
                var SKU = getJsonValue(obj.Item[i].SKU);
481
                var HitCount = getJsonValue(obj.Item[i].HitCount);
482
                var n = (SKU === undefined ? 0 : SKU.indexOf(" - "));
483
                var row;
484
                var str;
485
                var code;
486
 
487
                if (n > 0) {
488
                    code = SKU.substr(n + 3);
489
                    code = code.substr(code.indexOf(" ") + 1);
490
                    str = '<a href="' + configSearchUrl;
491
                    str += code;
492
                    str += configSearchUrlPart2 + '" target="_blank">';
493
                    str += SKU.substr(n + 3);
494
                    str += '</a>';
495
                    document.getElementById('ProductId' + ItemID).innerHTML = str;
496
                    x = document.getElementById("itemTable");
497
                    row = document.getElementById('ProductId' + ItemID).parentNode.rowIndex;
498
                    setCellsAttribute(x, row, 5, "Price" + code);
499
                    setCellsAttribute(x, row, 6, "Active" + code);
500
                    setCellsAttribute(x, row, 7, "Lower" + code);
501
                    setCellsAttribute(x, row, 8, "Minimum" + code);
502
                    setCellsAttribute(x, row, 9, "Maximum" + code);
503
                    x.rows[row].cells[11].innerHTML = HitCount;
504
                    setCellsAttribute(x, row, 13, "Condition" + code);
505
                    setCellsAttribute(x, row, 14, "BetterCondition" + code);
506
                    setCellsAttribute(x, row, 17, "MinBetterCondition" + code);
507
                    setCellsAttribute(x, row, 18, "BetterConditionBreakdown" + code);
508
                    setCellsAttribute(x, row, 19, "SameConditionBreakdown" + code);
509
                } else {
510
                    row = document.getElementById('ProductId' + ItemID).parentNode.rowIndex;
511
                    document.getElementById("itemTable").deleteRow(row);
512
                }
513
            }
514
        } else {
515
            x.className += " process-errors";
516
            x.innerHTML += '<p class="w3-red"><strong>' + returnCode + ':</strong></p>';
517
 
6 - 518
            var errors = getJsonArray(obj.Errors);
2 - 519
            x.innerHTML += "<p>";
6 - 520
            for (i = 0; i < errors.length; i++) {
521
                x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 522
            }
523
            x.innerHTML += "</p>";
524
        }
525
 
526
        --productIdsToProcess;
527
        ++productIdsProcessed;
528
        updateProgressBar(maxProductIdsToProcess, productIdsProcessed);
529
    };
530
 
531
    xhr.send(xml);
532
}
533
 
534
function findViews(itemIdList) {
535
    var i;
536
    var xml;
537
 
538
    var xw = new XMLWriter('UTF-8', '1.0');
539
    var xhr = new XMLHttpRequest();
540
 
541
    xw.writeStartDocument();
542
    xw.writeStartElement("GetMultipleItemsRequest");
543
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
544
 
545
    for (i = 0; i < itemIdList.length; i++) {
546
        xw.writeElementString('ItemID', itemIdList[i]);
547
    }
548
 
549
    xw.writeElementString('ErrorLanguage', 'en_US');
550
    xw.writeElementString('Version', configeBayShoppingVersion);
551
    xw.writeElementString('WarningLevel', configWarningLevel);
552
 
553
    xw.writeEndElement(); /* xmlrequest */
554
    xw.writeEndDocument();
555
 
556
    xhr.open('POST', configProxyUrl, true);
557
    xhr.setRequestHeader('Content-Type', 'text/xml');
558
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
559
    xhr.setRequestHeader('X-EBAY-API-VERSION', configeBayShoppingVersion);
560
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', 'GetMultipleItems');
561
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
562
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
563
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
564
    xhr.setRequestHeader('X-EBAY-API-REQUEST-ENCODING', 'XML');
565
    xhr.setRequestHeader('X-Proxy-URL', configeBayShopping);
566
 
567
    xml = xw.flush();
568
    xw.close();
569
 
570
    xhr.onload = function() {
571
        var obj = XMLparse(xhr.responseXML);
572
 
573
        var returnCode = obj.Ack;
574
 
575
        var x = document.getElementById("results");
576
 
577
        if (returnCode == 'Success') {
578
            for (i = 0; i < obj.Item.length; i++) {
579
                var ItemID = getJsonValue(obj.Item[i].ItemID);
580
                var HitCount = getJsonValue(obj.Item[i].HitCount);
581
 
582
                document.getElementById('Views' + ItemID).innerHTML = HitCount;
583
            }
584
        } else {
585
            x.className += " process-errors";
586
            x.innerHTML += '<p class="w3-red"><strong>' + returnCode + ':</strong></p>';
587
 
6 - 588
            var errors = getJsonArray(obj.Errors);
2 - 589
            x.innerHTML += "<p>";
6 - 590
            for (i = 0; i < errors.length; i++) {
591
                x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 592
            }
593
            x.innerHTML += "</p>";
594
        }
595
 
596
        --productIdsToProcess;
597
        ++productIdsProcessed;
598
        updateProgressBar(maxProductIdsToProcess, productIdsProcessed);
599
    };
600
 
601
    xhr.send(xml);
602
}
603
 
604
function priceProductIds() {
605
    var i;
606
    var price;
607
    var lowest;
608
    var difference;
609
    var percentage;
610
    var noPricedLower;
611
    var noActive;
612
    var noBetterCondition;
613
    var percLower;
614
    var x = document.getElementById("itemTable");
615
 
616
    initProgressBar('Retrieving Prices (3/3)');
617
 
618
    productsToPrice = 0;
619
    maxProductsToPrice = 0;
620
    productsPriced = 0;
621
 
622
    for (i = 1; i < x.rows.length; i++) {
4 - 623
        if (x.rows[i].cells[4].innerText.length > 0) {
624
            ++productsToPrice;
625
            ++maxProductsToPrice;
626
            findProductPrices(x.rows[i].cells[4].innerText, 1);
627
        }
2 - 628
    }
629
 
630
    function checkProductsToPrice() {
631
        if (productsToPrice > 0) {
632
            window.setTimeout(checkProductsToPrice, 100); // wait 100 milliseconds
633
        } else {
634
            /*
635
                xxxxx
636
                Minimum of 5 comparison listings
637
                (Take out lowest and highest price before calculating the average)
638
                (Don't go under $4.98)
639
                (Price items below cheapest item with better condition)
640
                Price within the first 20-25% listing (by number)
641
                (Price below the average price)
642
                adjust BIN (buy it now) when changing the price: No BIN under $10; minimum accepted 65%, auto-accepted 85+%
643
                (disregard certain sellers (for now decluttr and zuber, list could be expanded))
644
            */
645
            for (i = (x.rows.length - 1); i > 0; i--) {
646
                noPricedLower = Number(x.rows[i].cells[7].innerHTML);
647
                noActive = Number(x.rows[i].cells[6].innerHTML);
648
 
649
                if (noActive < 6) {
650
                    document.getElementById("itemTable").deleteRow(i);
651
                    continue;
652
                }
653
 
654
                if (noPricedLower > 0) {
655
                    price = Number(x.rows[i].cells[5].innerHTML.substr(1));
656
                    lowest = Number(x.rows[i].cells[8].innerHTML.substr(1));
657
                    difference = price - lowest;
658
                    percentage = 100.00 - (lowest / price * 100.00);
659
                    x.rows[i].cells[10].innerHTML = "$" + difference.toFixed(2) + " (" + percentage.toFixed(2) + "%)";
660
 
661
                    percLower = (noPricedLower / noActive) * 100.00;
662
                    if (noPricedLower > 24.99) {
663
                        x.rows[i].cells[5].style.color = "red";
664
                        x.rows[i].cells[7].style.color = "red";
665
                    } else {
666
                        document.getElementById("itemTable").deleteRow(i);
667
                        continue;
668
                    }
669
 
670
                    if (difference < configDifference || percentage < configPercentage || price < configAbsoluteMinPrice) {
671
                        document.getElementById("itemTable").deleteRow(i);
672
                        continue;
673
                    } else {
674
                        x.rows[i].cells[5].style.color = "red";
675
                        x.rows[i].cells[10].style.color = "red";
676
                    }
677
                } else if (noPricedLower === 0) {
678
                    noBetterCondition = Number(x.rows[i].cells[14].innerHTML);
679
                    if (noActive == (noBetterCondition + 1)) {
680
                        document.getElementById("itemTable").deleteRow(i);
681
                        continue;
682
                    }
683
 
684
                    price = Number(x.rows[i].cells[5].innerHTML.substr(1));
685
                    lowest = Number(x.rows[i].cells[8].innerHTML.substr(1));
686
                    difference = price - lowest;
687
                    percentage = 100.00 - (lowest / price * 100.00);
688
                    x.rows[i].cells[10].innerHTML = "$" + difference.toFixed(2) + " (" + percentage.toFixed(2) + "%)";
689
 
690
                    if ((difference * -1.00) < configDifference && (percentage * -1.00) < configPercentage) {
691
                        document.getElementById("itemTable").deleteRow(i);
692
                        continue;
693
                    } else {
694
                        x.rows[i].cells[5].style.color = "green";
695
                        x.rows[i].cells[10].style.color = "green";
696
                    }
697
                    continue;
698
                }
699
            }
700
 
701
            endProgressBar();
702
 
703
            x = document.getElementById("results");
704
            x.innerHTML += '<p><strong>Sorting Report.....</strong></p>';
705
 
706
            sortTableDesc("itemTable", 6);
707
 
708
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';
709
            if (!x.className.includes("process-errors")) {
710
                setTimeout(function() {
711
                    x.className = x.className.replace(" w3-show", "");
712
                }, 3000);
713
            }
714
        }
715
    }
716
 
717
    checkProductsToPrice();
718
}
719
 
720
function findProductPrices(productId, pageNumber) {
721
    var n = productId.indexOf(" ");
722
    var productIdType = productId.substr(0, n);
4 - 723
    var keyword = productId.substr(n + 1);
2 - 724
 
725
    url = configeBayFinding + "?";
726
    if (productIdType == 'ReferenceID') {
727
        url += "OPERATION-NAME=findItemsByProduct";
728
    } else {
729
        url += "OPERATION-NAME=findItemsAdvanced";
730
    }
731
    url += "&RESPONSE-DATA-FORMAT=JSON";
732
    url += "&SECURITY-APPNAME=" + configAppid;
733
    url += "&SERVICE-VERSION=" + configeBayFindingVersion;
734
    url += "&GLOBAL-ID=EBAY-US";
735
    url += "&buyerPostalCode=";
736
    url += configZip;
737
    url += "&paginationInput.entriesPerPage=100";
738
    url += "&paginationInput.pageNumber=";
739
    url += pageNumber;
740
 
741
    if (productIdType == 'ReferenceID') {
742
        url += "&productId.@type=";
743
        url += productIdType;
744
        url += "&productId=";
4 - 745
        url += keyword;
2 - 746
    } else {
747
        url += "&keywords=";
4 - 748
        url += keyword;
2 - 749
    }
750
 
751
    url += "&itemFilter(0).name=ExcludeSeller";
752
    url += "&itemFilter(0).value=";
753
    url += configeBaySellerName;
754
 
755
    var xhttp = new XMLHttpRequest();
756
 
757
    xhttp.onreadystatechange = function() {
758
        if (this.readyState == 4) {
759
            _cb_findProductPrices(JSON.parse(this.responseText));
760
        }
761
    };
762
 
763
 
764
    xhttp.open("GET", configProxyUrl, true);
765
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
766
    xhttp.send();
6 - 767
 
2 - 768
}
769
 
770
function _cb_findProductPrices(root) {
771
    var array;
772
    var response;
773
    var ack;
774
    var productId;
775
    var i;
776
    var currentPrice;
777
    var Title = "";
778
    var noLower;
779
    var noActive;
780
    var minPrice;
781
    var maxPrice;
782
    var conditionId;
783
    var currentConditionId;
784
    var noBetterCondition;
785
    var myPrice;
786
    var currentPriceInt;
787
    var minBetterCondition;
788
    var betterConditionbBreakdown = [];
789
    var sameConditionbBreakdown = [];
790
 
791
    if (root.findItemsAdvancedResponse !== undefined) {
792
        response = root.findItemsAdvancedResponse[0];
793
    } else if (root.findItemsByProductResponse !== undefined) {
794
        response = root.findItemsByProductResponse[0];
795
    } else {
796
        --productsToPrice;
797
        ++productsPriced;
798
        updateProgressBar(maxProductsToPrice, productsPriced);
799
        return;
800
    }
801
 
802
    ack = response.ack;
803
    if (ack != 'Success') {
4 - 804
        printeBayAPIError('Get Prices', response);
2 - 805
 
806
        if (ack == 'Failure' || ack == 'PartialFailure') {
807
            --productsToPrice;
808
            ++productsPriced;
809
            updateProgressBar(maxProductsToPrice, productsPriced);
810
            return;
811
        }
812
    }
813
 
814
    if (root.findItemsAdvancedResponse !== undefined) {
815
        array = typeof root.findItemsAdvancedResponse[0] != 'object' ? JSON.parse(root.findItemsAdvancedResponse[0]) : root.findItemsAdvancedResponse[0].searchResult[0].item;
816
        response = root.findItemsAdvancedResponse[0];
817
        url = new URL(response.itemSearchURL);
818
        productId = url.searchParams.get("_nkw");
819
    } else {
820
        array = typeof root.findItemsByProductResponse[0] != 'object' ? JSON.parse(root.findItemsByProductResponse[0]) : root.findItemsByProductResponse[0].searchResult[0].item;
821
        url = new URL(response.itemSearchURL);
822
        productId = url.searchParams.get("_productid");
823
    }
824
 
825
    var items = response.searchResult[0].item || [];
826
    noActive = Number(document.getElementById('Active' + productId).innerHTML);
827
    noLower = Number(document.getElementById('Lower' + productId).innerHTML);
828
    myPrice = Number(document.getElementById('Price' + productId).innerHTML.substr(1));
829
    minPrice = Number(document.getElementById('Minimum' + productId).innerHTML.substr(1));
830
    maxPrice = Number(document.getElementById('Maximum' + productId).innerHTML.substr(1));
831
    conditionId = Number(document.getElementById('Condition' + productId).innerHTML);
832
    noBetterCondition = Number(document.getElementById('BetterCondition' + productId).innerHTML);
833
    minBetterCondition = Number(document.getElementById('MinBetterCondition' + productId).innerHTML);
834
    betterConditionbBreakdown = JSON.parse(document.getElementById('BetterConditionBreakdown' + productId).innerHTML);
835
    sameConditionbBreakdown = JSON.parse(document.getElementById('SameConditionBreakdown' + productId).innerHTML);
836
 
837
    for (i = 0; i < items.length; i++) {
838
        Title = items[i].title[0].toLowerCase();
839
        if (Title.includes("disc only") > 0 ||
840
            Title.includes("disk only") > 0 ||
841
            Title.includes("only disc") > 0 ||
842
            Title.includes("only disk") > 0 ||
843
            Title.search(/dis[ck].*only/) > 0) {
844
            continue; // exclude "disc only listing
845
        }
846
 
847
        currentConditionId = (items[i].condition === undefined ? 0 : Number(items[i].condition[0].conditionId));
848
        currentPrice = Number(items[i].sellingStatus[0].convertedCurrentPrice[0].__value__);
849
        currentPriceInt = Math.ceil(currentPrice);
850
 
851
        if (currentConditionId > conditionId) {
852
            continue; // Like for like conditions only
853
        } else if (currentConditionId > conditionId) {
854
            if (minBetterCondition < 0.01 || minBetterCondition > currentPrice) {
855
                minBetterCondition = currentPrice;
856
            }
857
 
858
            ++noBetterCondition;
859
        }
860
 
861
        if (items[i].sellingStatus[0].bidCount === 0 && items[i].listingInfo[0].convertedBuyItNowPrice !== undefined) {
862
            currentPrice = Number(items[i].listingInfo[0].convertedBuyItNowPrice[0].__value__);
863
        }
864
 
865
        if (items[i].shippingInfo[0].shippingServiceCost) {
866
            currentPrice += Number(items[i].shippingInfo[0].shippingServiceCost[0].__value__);
867
        }
868
 
869
        if (currentConditionId > conditionId) {
870
            if (betterConditionbBreakdown[currentPriceInt] === undefined) {
871
                betterConditionbBreakdown[currentPriceInt] = 0;
872
            }
873
            ++betterConditionbBreakdown[currentPriceInt];
874
        } else {
875
            if (sameConditionbBreakdown[currentPriceInt] === undefined) {
876
                sameConditionbBreakdown[currentPriceInt] = 0;
877
            }
878
            ++sameConditionbBreakdown[currentPriceInt];
879
        }
880
 
881
        if (currentPrice < myPrice) {
882
            ++noLower;
883
        }
884
 
885
        if (minPrice < 0.01 || minPrice > currentPrice) {
886
            minPrice = currentPrice;
887
        }
888
 
889
        if (maxPrice < 0.01 || maxPrice < currentPrice) {
890
            maxPrice = currentPrice;
891
        }
892
 
893
        ++noActive;
894
    }
895
 
896
    document.getElementById('Active' + productId).innerHTML = noActive;
897
    document.getElementById('Lower' + productId).innerHTML = noLower;
898
    document.getElementById('Minimum' + productId).innerHTML = '$' + minPrice.toFixed(2);
899
    document.getElementById('Maximum' + productId).innerHTML = '$' + maxPrice.toFixed(2);
900
    document.getElementById('BetterCondition' + productId).innerHTML = noBetterCondition;
901
    document.getElementById('MinBetterCondition' + productId).innerHTML = minBetterCondition;
902
    document.getElementById('BetterConditionBreakdown' + productId).innerHTML = JSON.stringify(betterConditionbBreakdown);
903
    document.getElementById('SameConditionBreakdown' + productId).innerHTML = JSON.stringify(sameConditionbBreakdown);
904
 
905
    if (Number(response.paginationOutput[0].totalPages) > Number(response.paginationOutput[0].pageNumber)) {
906
        ++productsToPrice;
907
        ++maxProductsToPrice;
908
        var row = document.getElementById('Lower' + productId).parentNode.rowIndex;
909
        findProductPrices(document.getElementById("itemTable").rows[row].cells[4].innerText, Number(response.paginationOutput[0].pageNumber) + 1);
910
    }
911
 
912
    --productsToPrice;
913
    ++productsPriced;
914
    updateProgressBar(maxProductsToPrice, productsPriced);
915
}
916
 
917
function changePrice(itemId) {
918
    var i;
919
    var newPrice = parseFloat(document.getElementById('PriceAdj' + itemId).value).toFixed(2);
920
 
921
    if (isNaN(newPrice) || newPrice < configAdjMinPrice) {
922
        document.getElementById('PriceAdj' + itemId).value = '';
923
        return;
924
    }
925
 
926
    document.getElementById('PriceAdj' + itemId).value = newPrice;
927
 
928
    if (eBayAuthTokenFlag === false) {
929
        return;
930
    }
931
 
932
    var xw = new XMLWriter('UTF-8', '1.0');
933
    var xhr = new XMLHttpRequest();
934
 
935
    if (!createAddXML(xw, xhr, 'ReviseItemRequest', 'ReviseItem', itemId, newPrice)) {
936
        return;
937
    }
938
 
939
    xml = xw.flush();
940
    xw.close();
941
 
942
    xhr.onload = function() {
943
        var obj = XMLparse(xhr.responseXML);
944
 
945
        var returnCode = obj.Ack;
946
 
947
        var x = document.getElementById("results");
948
        if (x.className.indexOf("w3-show") == -1) {
949
            x.className += " w3-show";
950
        }
951
        x.className = x.className.replace(" process-errors", "");
952
 
953
        if (returnCode == 'Success' || (returnCode == 'Warning' && (obj.Errors.ErrorCode == '21917108' || obj.Errors.ErrorCode == '23007'))) {
954
            document.getElementById('PriceAdj' + itemId).style.color = "green";
955
 
956
            x.innerHTML = '<p><strong>' + returnCode + '</strong></p>';
957
 
958
            if (returnCode == 'Warning') {
959
                x.innerHTML += "<p>" + obj.Errors.SeverityCode + " (" + obj.Errors.ErrorCode + "): " + escapeHtml(obj.Errors.LongMessage) + "</p>";
960
                x.className += " process-errors";
961
            }
962
            var fees = obj.Fees;
963
            x.innerHTML += "<p>";
964
            for (i = 0; i < fees.length; i++) {
965
                if (fees[i].Fee.text !== "0.0") {
966
                    x.innerHTML += fees[i].Name + ": $" + Number(fees[i].Fee.text).toFixed(2) + "<br/>";
967
                }
968
            }
969
            x.innerHTML += "</p>";
970
 
971
            if (obj.DiscountReason) {
972
                x.innerHTML += "<p>Discount Reason: " + obj.DiscountReason + "</p>";
973
            }
974
 
975
            var recommendations = obj.ListingRecommendations;
976
            if (recommendations) {
977
                if (recommendations.length > 0) {
978
                    for (i = 0; i < recommendations.length; i++) {
979
                        x.innerHTML += decode(recommendations[i]);
980
                    }
981
                } else {
982
                    x.innerHTML += decode(recommendations);
983
                }
984
            }
985
        } else {
986
            document.getElementById('PriceAdj' + itemId).style.color = "red";
987
            x.innerHTML = "<p><strong>" + returnCode + ":</strong></p>";
988
            x.className += " process-errors";
989
 
6 - 990
            var errors = getJsonArray(obj.Errors);
2 - 991
            x.innerHTML += "<p>";
6 - 992
            for (i = 0; i < errors.length; i++) {
993
                x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 994
            }
995
            x.innerHTML += "</p>";
996
        }
997
 
998
        if (obj.Message) {
999
            x.innerHTML += obj.Message;
1000
        }
1001
 
1002
        if (!x.className.includes("process-errors")) {
1003
            setTimeout(function() {
1004
                x.className = x.className.replace(" w3-show", "");
1005
            }, 3000);
1006
        }
1007
    };
1008
 
1009
    xhr.send(xml);
1010
}
1011
 
1012
function createAddXML(xw, xhr, xmlrequest, callname, itemId, newPrice) {
1013
    xw.writeStartDocument();
1014
    xw.writeStartElement(xmlrequest);
1015
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
1016
 
1017
    xw.writeStartElement('RequesterCredentials');
1018
    xw.writeElementString('eBayAuthToken', eBayAuthToken);
1019
    xw.writeEndElement(); /* RequesterCredentials */
1020
 
1021
    xw.writeStartElement('Item');
1022
 
1023
    xw.writeStartElement('StartPrice');
1024
    xw.writeAttributeString('currencyID', 'USD');
1025
    xw.writeString(newPrice);
1026
    xw.writeEndElement(); /* StartPrice */
1027
 
1028
    //xw.writeElementString('ItemID', itemId);
1029
    xw.writeString('<ItemID>' + itemId + '</ItemID>');
1030
 
1031
    if (document.getElementById('BestOffer' + itemId).innerHTML == 'true') {
1032
        if (newPrice >= 14.99) {
1033
            var autoAcceptPrice = newPrice * configAutoAcceptPrice;
1034
            var minBestOfferPrice = newPrice * configMinBestOfferPrice;
1035
 
1036
            xw.writeStartElement('BestOfferDetails');
1037
            xw.writeElementString('BestOfferEnabled', 'true');
1038
            xw.writeEndElement(); /* BestOfferDetails */
1039
            xw.writeStartElement('ListingDetails');
1040
            xw.writeStartElement('BestOfferAutoAcceptPrice');
1041
            xw.writeAttributeString('currencyID', 'USD');
1042
            xw.writeString(autoAcceptPrice.toFixed(2));
1043
            xw.writeEndElement(); /* BestOfferAutoAcceptPrice */
1044
            xw.writeStartElement('MinimumBestOfferPrice');
1045
            xw.writeAttributeString('currencyID', 'USD');
1046
            xw.writeString(minBestOfferPrice.toFixed(2));
1047
            xw.writeEndElement(); /* MinimumBestOfferPrice */
1048
            xw.writeEndElement(); /* ListingDetails */
1049
        } else {
1050
            xw.writeStartElement('BestOfferDetails');
1051
            xw.writeElementString('BestOfferEnabled', 'false');
1052
            xw.writeEndElement(); /* BestOfferDetails */
1053
        }
1054
    }
1055
 
1056
    xw.writeEndElement(); /* Item */
1057
 
1058
    xw.writeElementString('ErrorLanguage', 'en_US');
1059
    xw.writeElementString('Version', configeBayTradingVersion);
1060
    xw.writeElementString('WarningLevel', configWarningLevel);
1061
 
1062
    xw.writeEndElement(); /* xmlrequest */
1063
    xw.writeEndDocument();
1064
 
1065
    xhr.open('POST', configProxyUrl, true);
1066
    xhr.setRequestHeader('Content-Type', 'text/xml');
1067
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
1068
    xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
1069
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
1070
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
1071
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
1072
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
1073
    xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
1074
 
1075
    return true;
1076
}
1077
 
1078
function connected() {
1079
    var x;
1080
 
1081
    eBayAuthTokenFlag = true;
1082
    document.getElementById("connected").innerHTML += " (Connected)";
1083
 
1084
    x = document.getElementById("login");
1085
    x.className = x.className.replace(" w3-show", "");
1086
 
1087
    x = document.getElementById("results");
1088
    x.innerHTML = "";
1089
    x.className = x.className.replace(" w3-show", "");
1090
}
1091
 
1092
    </script>
17 - 1093
    <script>includeHTML();</script>
2 - 1094
 
1095
</body>
1096
</html>