Subversion Repositories munaweb

Rev

Rev 17 | Rev 30 | 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;
19 - 474
        var str;
2 - 475
 
476
        var x = document.getElementById("results");
477
 
478
        if (returnCode == 'Success') {
479
            for (i = 0; i < obj.Item.length; i++) {
480
                var ItemID = getJsonValue(obj.Item[i].ItemID);
481
                var SKU = getJsonValue(obj.Item[i].SKU);
482
                var HitCount = getJsonValue(obj.Item[i].HitCount);
483
                var n = (SKU === undefined ? 0 : SKU.indexOf(" - "));
484
                var row;
485
                var str;
486
                var code;
487
 
488
                if (n > 0) {
489
                    code = SKU.substr(n + 3);
490
                    code = code.substr(code.indexOf(" ") + 1);
491
                    str = '<a href="' + configSearchUrl;
492
                    str += code;
493
                    str += configSearchUrlPart2 + '" target="_blank">';
494
                    str += SKU.substr(n + 3);
495
                    str += '</a>';
496
                    document.getElementById('ProductId' + ItemID).innerHTML = str;
497
                    x = document.getElementById("itemTable");
498
                    row = document.getElementById('ProductId' + ItemID).parentNode.rowIndex;
499
                    setCellsAttribute(x, row, 5, "Price" + code);
500
                    setCellsAttribute(x, row, 6, "Active" + code);
501
                    setCellsAttribute(x, row, 7, "Lower" + code);
502
                    setCellsAttribute(x, row, 8, "Minimum" + code);
503
                    setCellsAttribute(x, row, 9, "Maximum" + code);
504
                    x.rows[row].cells[11].innerHTML = HitCount;
505
                    setCellsAttribute(x, row, 13, "Condition" + code);
506
                    setCellsAttribute(x, row, 14, "BetterCondition" + code);
507
                    setCellsAttribute(x, row, 17, "MinBetterCondition" + code);
508
                    setCellsAttribute(x, row, 18, "BetterConditionBreakdown" + code);
509
                    setCellsAttribute(x, row, 19, "SameConditionBreakdown" + code);
510
                } else {
511
                    row = document.getElementById('ProductId' + ItemID).parentNode.rowIndex;
512
                    document.getElementById("itemTable").deleteRow(row);
513
                }
514
            }
515
        } else {
516
            x.className += " process-errors";
19 - 517
            str += '<p class="w3-red"><strong>' + returnCode + ':</strong></p>';
2 - 518
 
6 - 519
            var errors = getJsonArray(obj.Errors);
19 - 520
            str += "<p>";
6 - 521
            for (i = 0; i < errors.length; i++) {
19 - 522
                str += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 523
            }
19 - 524
            str += "</p>";
525
            x.innerHTML += str;
2 - 526
        }
527
 
528
        --productIdsToProcess;
529
        ++productIdsProcessed;
530
        updateProgressBar(maxProductIdsToProcess, productIdsProcessed);
531
    };
532
 
533
    xhr.send(xml);
534
}
535
 
536
function findViews(itemIdList) {
537
    var i;
538
    var xml;
539
 
540
    var xw = new XMLWriter('UTF-8', '1.0');
541
    var xhr = new XMLHttpRequest();
542
 
543
    xw.writeStartDocument();
544
    xw.writeStartElement("GetMultipleItemsRequest");
545
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
546
 
547
    for (i = 0; i < itemIdList.length; i++) {
548
        xw.writeElementString('ItemID', itemIdList[i]);
549
    }
550
 
551
    xw.writeElementString('ErrorLanguage', 'en_US');
552
    xw.writeElementString('Version', configeBayShoppingVersion);
553
    xw.writeElementString('WarningLevel', configWarningLevel);
554
 
555
    xw.writeEndElement(); /* xmlrequest */
556
    xw.writeEndDocument();
557
 
558
    xhr.open('POST', configProxyUrl, true);
559
    xhr.setRequestHeader('Content-Type', 'text/xml');
560
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
561
    xhr.setRequestHeader('X-EBAY-API-VERSION', configeBayShoppingVersion);
562
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', 'GetMultipleItems');
563
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
564
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
565
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
566
    xhr.setRequestHeader('X-EBAY-API-REQUEST-ENCODING', 'XML');
567
    xhr.setRequestHeader('X-Proxy-URL', configeBayShopping);
568
 
569
    xml = xw.flush();
570
    xw.close();
571
 
572
    xhr.onload = function() {
19 - 573
        var jsonObj = XMLparse(xhr.responseXML, false);
574
        var obj = jsonObj.GetMultipleItemsResponse;
2 - 575
        var returnCode = obj.Ack;
19 - 576
        var str;
2 - 577
 
578
        var x = document.getElementById("results");
579
 
580
        if (returnCode == 'Success') {
581
            for (i = 0; i < obj.Item.length; i++) {
582
                var ItemID = getJsonValue(obj.Item[i].ItemID);
583
                var HitCount = getJsonValue(obj.Item[i].HitCount);
584
 
585
                document.getElementById('Views' + ItemID).innerHTML = HitCount;
586
            }
587
        } else {
588
            x.className += " process-errors";
19 - 589
            str += '<p class="w3-red"><strong>' + returnCode + ':</strong></p>';
2 - 590
 
6 - 591
            var errors = getJsonArray(obj.Errors);
19 - 592
            str += "<p>";
6 - 593
            for (i = 0; i < errors.length; i++) {
19 - 594
                str += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 595
            }
19 - 596
            str += "</p>";
597
            x.innerHTML += str;
2 - 598
        }
599
 
600
        --productIdsToProcess;
601
        ++productIdsProcessed;
602
        updateProgressBar(maxProductIdsToProcess, productIdsProcessed);
603
    };
604
 
605
    xhr.send(xml);
606
}
607
 
608
function priceProductIds() {
609
    var i;
610
    var price;
611
    var lowest;
612
    var difference;
613
    var percentage;
614
    var noPricedLower;
615
    var noActive;
616
    var noBetterCondition;
617
    var percLower;
618
    var x = document.getElementById("itemTable");
619
 
620
    initProgressBar('Retrieving Prices (3/3)');
621
 
622
    productsToPrice = 0;
623
    maxProductsToPrice = 0;
624
    productsPriced = 0;
625
 
626
    for (i = 1; i < x.rows.length; i++) {
4 - 627
        if (x.rows[i].cells[4].innerText.length > 0) {
628
            ++productsToPrice;
629
            ++maxProductsToPrice;
630
            findProductPrices(x.rows[i].cells[4].innerText, 1);
631
        }
2 - 632
    }
633
 
634
    function checkProductsToPrice() {
635
        if (productsToPrice > 0) {
636
            window.setTimeout(checkProductsToPrice, 100); // wait 100 milliseconds
637
        } else {
638
            /*
639
                xxxxx
640
                Minimum of 5 comparison listings
641
                (Take out lowest and highest price before calculating the average)
642
                (Don't go under $4.98)
643
                (Price items below cheapest item with better condition)
644
                Price within the first 20-25% listing (by number)
645
                (Price below the average price)
646
                adjust BIN (buy it now) when changing the price: No BIN under $10; minimum accepted 65%, auto-accepted 85+%
647
                (disregard certain sellers (for now decluttr and zuber, list could be expanded))
648
            */
649
            for (i = (x.rows.length - 1); i > 0; i--) {
650
                noPricedLower = Number(x.rows[i].cells[7].innerHTML);
651
                noActive = Number(x.rows[i].cells[6].innerHTML);
652
 
653
                if (noActive < 6) {
654
                    document.getElementById("itemTable").deleteRow(i);
655
                    continue;
656
                }
657
 
658
                if (noPricedLower > 0) {
659
                    price = Number(x.rows[i].cells[5].innerHTML.substr(1));
660
                    lowest = Number(x.rows[i].cells[8].innerHTML.substr(1));
661
                    difference = price - lowest;
662
                    percentage = 100.00 - (lowest / price * 100.00);
663
                    x.rows[i].cells[10].innerHTML = "$" + difference.toFixed(2) + " (" + percentage.toFixed(2) + "%)";
664
 
665
                    percLower = (noPricedLower / noActive) * 100.00;
666
                    if (noPricedLower > 24.99) {
667
                        x.rows[i].cells[5].style.color = "red";
668
                        x.rows[i].cells[7].style.color = "red";
669
                    } else {
670
                        document.getElementById("itemTable").deleteRow(i);
671
                        continue;
672
                    }
673
 
674
                    if (difference < configDifference || percentage < configPercentage || price < configAbsoluteMinPrice) {
675
                        document.getElementById("itemTable").deleteRow(i);
676
                        continue;
677
                    } else {
678
                        x.rows[i].cells[5].style.color = "red";
679
                        x.rows[i].cells[10].style.color = "red";
680
                    }
681
                } else if (noPricedLower === 0) {
682
                    noBetterCondition = Number(x.rows[i].cells[14].innerHTML);
683
                    if (noActive == (noBetterCondition + 1)) {
684
                        document.getElementById("itemTable").deleteRow(i);
685
                        continue;
686
                    }
687
 
688
                    price = Number(x.rows[i].cells[5].innerHTML.substr(1));
689
                    lowest = Number(x.rows[i].cells[8].innerHTML.substr(1));
690
                    difference = price - lowest;
691
                    percentage = 100.00 - (lowest / price * 100.00);
692
                    x.rows[i].cells[10].innerHTML = "$" + difference.toFixed(2) + " (" + percentage.toFixed(2) + "%)";
693
 
694
                    if ((difference * -1.00) < configDifference && (percentage * -1.00) < configPercentage) {
695
                        document.getElementById("itemTable").deleteRow(i);
696
                        continue;
697
                    } else {
698
                        x.rows[i].cells[5].style.color = "green";
699
                        x.rows[i].cells[10].style.color = "green";
700
                    }
701
                    continue;
702
                }
703
            }
704
 
705
            endProgressBar();
706
 
707
            x = document.getElementById("results");
708
            x.innerHTML += '<p><strong>Sorting Report.....</strong></p>';
709
 
710
            sortTableDesc("itemTable", 6);
711
 
712
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';
713
            if (!x.className.includes("process-errors")) {
714
                setTimeout(function() {
715
                    x.className = x.className.replace(" w3-show", "");
716
                }, 3000);
717
            }
718
        }
719
    }
720
 
721
    checkProductsToPrice();
722
}
723
 
724
function findProductPrices(productId, pageNumber) {
725
    var n = productId.indexOf(" ");
726
    var productIdType = productId.substr(0, n);
4 - 727
    var keyword = productId.substr(n + 1);
2 - 728
 
729
    url = configeBayFinding + "?";
730
    if (productIdType == 'ReferenceID') {
731
        url += "OPERATION-NAME=findItemsByProduct";
732
    } else {
733
        url += "OPERATION-NAME=findItemsAdvanced";
734
    }
735
    url += "&RESPONSE-DATA-FORMAT=JSON";
736
    url += "&SECURITY-APPNAME=" + configAppid;
737
    url += "&SERVICE-VERSION=" + configeBayFindingVersion;
738
    url += "&GLOBAL-ID=EBAY-US";
739
    url += "&buyerPostalCode=";
740
    url += configZip;
741
    url += "&paginationInput.entriesPerPage=100";
742
    url += "&paginationInput.pageNumber=";
743
    url += pageNumber;
744
 
745
    if (productIdType == 'ReferenceID') {
746
        url += "&productId.@type=";
747
        url += productIdType;
748
        url += "&productId=";
4 - 749
        url += keyword;
2 - 750
    } else {
751
        url += "&keywords=";
4 - 752
        url += keyword;
2 - 753
    }
754
 
755
    url += "&itemFilter(0).name=ExcludeSeller";
756
    url += "&itemFilter(0).value=";
757
    url += configeBaySellerName;
758
 
759
    var xhttp = new XMLHttpRequest();
760
 
761
    xhttp.onreadystatechange = function() {
762
        if (this.readyState == 4) {
763
            _cb_findProductPrices(JSON.parse(this.responseText));
764
        }
765
    };
766
 
767
 
768
    xhttp.open("GET", configProxyUrl, true);
769
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
770
    xhttp.send();
6 - 771
 
2 - 772
}
773
 
774
function _cb_findProductPrices(root) {
775
    var array;
776
    var response;
777
    var ack;
778
    var productId;
779
    var i;
780
    var currentPrice;
781
    var Title = "";
782
    var noLower;
783
    var noActive;
784
    var minPrice;
785
    var maxPrice;
786
    var conditionId;
787
    var currentConditionId;
788
    var noBetterCondition;
789
    var myPrice;
790
    var currentPriceInt;
791
    var minBetterCondition;
792
    var betterConditionbBreakdown = [];
793
    var sameConditionbBreakdown = [];
794
 
795
    if (root.findItemsAdvancedResponse !== undefined) {
796
        response = root.findItemsAdvancedResponse[0];
797
    } else if (root.findItemsByProductResponse !== undefined) {
798
        response = root.findItemsByProductResponse[0];
799
    } else {
800
        --productsToPrice;
801
        ++productsPriced;
802
        updateProgressBar(maxProductsToPrice, productsPriced);
803
        return;
804
    }
805
 
806
    ack = response.ack;
807
    if (ack != 'Success') {
4 - 808
        printeBayAPIError('Get Prices', response);
2 - 809
 
810
        if (ack == 'Failure' || ack == 'PartialFailure') {
811
            --productsToPrice;
812
            ++productsPriced;
813
            updateProgressBar(maxProductsToPrice, productsPriced);
814
            return;
815
        }
816
    }
817
 
818
    if (root.findItemsAdvancedResponse !== undefined) {
819
        array = typeof root.findItemsAdvancedResponse[0] != 'object' ? JSON.parse(root.findItemsAdvancedResponse[0]) : root.findItemsAdvancedResponse[0].searchResult[0].item;
820
        response = root.findItemsAdvancedResponse[0];
821
        url = new URL(response.itemSearchURL);
822
        productId = url.searchParams.get("_nkw");
823
    } else {
824
        array = typeof root.findItemsByProductResponse[0] != 'object' ? JSON.parse(root.findItemsByProductResponse[0]) : root.findItemsByProductResponse[0].searchResult[0].item;
825
        url = new URL(response.itemSearchURL);
826
        productId = url.searchParams.get("_productid");
827
    }
828
 
829
    var items = response.searchResult[0].item || [];
830
    noActive = Number(document.getElementById('Active' + productId).innerHTML);
831
    noLower = Number(document.getElementById('Lower' + productId).innerHTML);
832
    myPrice = Number(document.getElementById('Price' + productId).innerHTML.substr(1));
833
    minPrice = Number(document.getElementById('Minimum' + productId).innerHTML.substr(1));
834
    maxPrice = Number(document.getElementById('Maximum' + productId).innerHTML.substr(1));
835
    conditionId = Number(document.getElementById('Condition' + productId).innerHTML);
836
    noBetterCondition = Number(document.getElementById('BetterCondition' + productId).innerHTML);
837
    minBetterCondition = Number(document.getElementById('MinBetterCondition' + productId).innerHTML);
838
    betterConditionbBreakdown = JSON.parse(document.getElementById('BetterConditionBreakdown' + productId).innerHTML);
839
    sameConditionbBreakdown = JSON.parse(document.getElementById('SameConditionBreakdown' + productId).innerHTML);
840
 
841
    for (i = 0; i < items.length; i++) {
842
        Title = items[i].title[0].toLowerCase();
843
        if (Title.includes("disc only") > 0 ||
844
            Title.includes("disk only") > 0 ||
845
            Title.includes("only disc") > 0 ||
846
            Title.includes("only disk") > 0 ||
847
            Title.search(/dis[ck].*only/) > 0) {
848
            continue; // exclude "disc only listing
849
        }
850
 
851
        currentConditionId = (items[i].condition === undefined ? 0 : Number(items[i].condition[0].conditionId));
852
        currentPrice = Number(items[i].sellingStatus[0].convertedCurrentPrice[0].__value__);
853
        currentPriceInt = Math.ceil(currentPrice);
854
 
855
        if (currentConditionId > conditionId) {
856
            continue; // Like for like conditions only
857
        } else if (currentConditionId > conditionId) {
858
            if (minBetterCondition < 0.01 || minBetterCondition > currentPrice) {
859
                minBetterCondition = currentPrice;
860
            }
861
 
862
            ++noBetterCondition;
863
        }
864
 
865
        if (items[i].sellingStatus[0].bidCount === 0 && items[i].listingInfo[0].convertedBuyItNowPrice !== undefined) {
866
            currentPrice = Number(items[i].listingInfo[0].convertedBuyItNowPrice[0].__value__);
867
        }
868
 
869
        if (items[i].shippingInfo[0].shippingServiceCost) {
870
            currentPrice += Number(items[i].shippingInfo[0].shippingServiceCost[0].__value__);
871
        }
872
 
873
        if (currentConditionId > conditionId) {
874
            if (betterConditionbBreakdown[currentPriceInt] === undefined) {
875
                betterConditionbBreakdown[currentPriceInt] = 0;
876
            }
877
            ++betterConditionbBreakdown[currentPriceInt];
878
        } else {
879
            if (sameConditionbBreakdown[currentPriceInt] === undefined) {
880
                sameConditionbBreakdown[currentPriceInt] = 0;
881
            }
882
            ++sameConditionbBreakdown[currentPriceInt];
883
        }
884
 
885
        if (currentPrice < myPrice) {
886
            ++noLower;
887
        }
888
 
889
        if (minPrice < 0.01 || minPrice > currentPrice) {
890
            minPrice = currentPrice;
891
        }
892
 
893
        if (maxPrice < 0.01 || maxPrice < currentPrice) {
894
            maxPrice = currentPrice;
895
        }
896
 
897
        ++noActive;
898
    }
899
 
900
    document.getElementById('Active' + productId).innerHTML = noActive;
901
    document.getElementById('Lower' + productId).innerHTML = noLower;
902
    document.getElementById('Minimum' + productId).innerHTML = '$' + minPrice.toFixed(2);
903
    document.getElementById('Maximum' + productId).innerHTML = '$' + maxPrice.toFixed(2);
904
    document.getElementById('BetterCondition' + productId).innerHTML = noBetterCondition;
905
    document.getElementById('MinBetterCondition' + productId).innerHTML = minBetterCondition;
906
    document.getElementById('BetterConditionBreakdown' + productId).innerHTML = JSON.stringify(betterConditionbBreakdown);
907
    document.getElementById('SameConditionBreakdown' + productId).innerHTML = JSON.stringify(sameConditionbBreakdown);
908
 
909
    if (Number(response.paginationOutput[0].totalPages) > Number(response.paginationOutput[0].pageNumber)) {
910
        ++productsToPrice;
911
        ++maxProductsToPrice;
912
        var row = document.getElementById('Lower' + productId).parentNode.rowIndex;
913
        findProductPrices(document.getElementById("itemTable").rows[row].cells[4].innerText, Number(response.paginationOutput[0].pageNumber) + 1);
914
    }
915
 
916
    --productsToPrice;
917
    ++productsPriced;
918
    updateProgressBar(maxProductsToPrice, productsPriced);
919
}
920
 
921
function changePrice(itemId) {
922
    var i;
923
    var newPrice = parseFloat(document.getElementById('PriceAdj' + itemId).value).toFixed(2);
924
 
925
    if (isNaN(newPrice) || newPrice < configAdjMinPrice) {
926
        document.getElementById('PriceAdj' + itemId).value = '';
927
        return;
928
    }
929
 
930
    document.getElementById('PriceAdj' + itemId).value = newPrice;
931
 
932
    if (eBayAuthTokenFlag === false) {
933
        return;
934
    }
935
 
936
    var xw = new XMLWriter('UTF-8', '1.0');
937
    var xhr = new XMLHttpRequest();
938
 
939
    if (!createAddXML(xw, xhr, 'ReviseItemRequest', 'ReviseItem', itemId, newPrice)) {
940
        return;
941
    }
942
 
943
    xml = xw.flush();
944
    xw.close();
945
 
946
    xhr.onload = function() {
19 - 947
        var jsonObj = XMLparse(xhr.responseXML, false);
948
        var obj = jsonObj.ReviseItemResponse;
2 - 949
        var returnCode = obj.Ack;
19 - 950
        var str = "";
2 - 951
 
952
        var x = document.getElementById("results");
953
        if (x.className.indexOf("w3-show") == -1) {
954
            x.className += " w3-show";
955
        }
956
        x.className = x.className.replace(" process-errors", "");
957
 
958
        if (returnCode == 'Success' || (returnCode == 'Warning' && (obj.Errors.ErrorCode == '21917108' || obj.Errors.ErrorCode == '23007'))) {
959
            document.getElementById('PriceAdj' + itemId).style.color = "green";
960
 
19 - 961
            str = '<p><strong>' + returnCode + '</strong></p>';
2 - 962
 
963
            if (returnCode == 'Warning') {
19 - 964
                str += "<p>" + obj.Errors.SeverityCode + " (" + obj.Errors.ErrorCode + "): " + escapeHtml(obj.Errors.LongMessage) + "</p>";
2 - 965
                x.className += " process-errors";
966
            }
19 - 967
            var fees = getJsonArray(obj.Fees.Fee);
968
            str += "<p>";
2 - 969
            for (i = 0; i < fees.length; i++) {
970
                if (fees[i].Fee.text !== "0.0") {
19 - 971
                    str += fees[i].Name + ": $" + Number(fees[i].Fee.text).toFixed(2) + "<br/>";
2 - 972
                }
973
            }
19 - 974
            str += "</p>";
2 - 975
 
976
            if (obj.DiscountReason) {
19 - 977
                str += "<p>Discount Reason: " + obj.DiscountReason + "</p>";
2 - 978
            }
979
 
19 - 980
            var recommendations = getJsonArray(obj.ListingRecommendations.Recommendation);
981
            for (i = 0; i < recommendations.length; i++) {
982
                str += decode(recommendations[i]);
2 - 983
            }
19 - 984
 
985
            x.innerHTML = str;
2 - 986
        } else {
987
            document.getElementById('PriceAdj' + itemId).style.color = "red";
19 - 988
            str = "<p><strong>" + returnCode + ":</strong></p>";
2 - 989
            x.className += " process-errors";
990
 
6 - 991
            var errors = getJsonArray(obj.Errors);
19 - 992
            str += "<p>";
6 - 993
            for (i = 0; i < errors.length; i++) {
19 - 994
                str += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 995
            }
19 - 996
            str += "</p>";
997
            x.innerHTML = str;
2 - 998
        }
999
 
1000
        if (obj.Message) {
1001
            x.innerHTML += obj.Message;
1002
        }
1003
 
1004
        if (!x.className.includes("process-errors")) {
1005
            setTimeout(function() {
1006
                x.className = x.className.replace(" w3-show", "");
1007
            }, 3000);
1008
        }
1009
    };
1010
 
1011
    xhr.send(xml);
1012
}
1013
 
1014
function createAddXML(xw, xhr, xmlrequest, callname, itemId, newPrice) {
1015
    xw.writeStartDocument();
1016
    xw.writeStartElement(xmlrequest);
1017
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
1018
 
1019
    xw.writeStartElement('RequesterCredentials');
1020
    xw.writeElementString('eBayAuthToken', eBayAuthToken);
1021
    xw.writeEndElement(); /* RequesterCredentials */
1022
 
1023
    xw.writeStartElement('Item');
1024
 
1025
    xw.writeStartElement('StartPrice');
1026
    xw.writeAttributeString('currencyID', 'USD');
1027
    xw.writeString(newPrice);
1028
    xw.writeEndElement(); /* StartPrice */
1029
 
1030
    //xw.writeElementString('ItemID', itemId);
1031
    xw.writeString('<ItemID>' + itemId + '</ItemID>');
1032
 
1033
    if (document.getElementById('BestOffer' + itemId).innerHTML == 'true') {
1034
        if (newPrice >= 14.99) {
1035
            var autoAcceptPrice = newPrice * configAutoAcceptPrice;
1036
            var minBestOfferPrice = newPrice * configMinBestOfferPrice;
1037
 
1038
            xw.writeStartElement('BestOfferDetails');
1039
            xw.writeElementString('BestOfferEnabled', 'true');
1040
            xw.writeEndElement(); /* BestOfferDetails */
1041
            xw.writeStartElement('ListingDetails');
1042
            xw.writeStartElement('BestOfferAutoAcceptPrice');
1043
            xw.writeAttributeString('currencyID', 'USD');
1044
            xw.writeString(autoAcceptPrice.toFixed(2));
1045
            xw.writeEndElement(); /* BestOfferAutoAcceptPrice */
1046
            xw.writeStartElement('MinimumBestOfferPrice');
1047
            xw.writeAttributeString('currencyID', 'USD');
1048
            xw.writeString(minBestOfferPrice.toFixed(2));
1049
            xw.writeEndElement(); /* MinimumBestOfferPrice */
1050
            xw.writeEndElement(); /* ListingDetails */
1051
        } else {
1052
            xw.writeStartElement('BestOfferDetails');
1053
            xw.writeElementString('BestOfferEnabled', 'false');
1054
            xw.writeEndElement(); /* BestOfferDetails */
1055
        }
1056
    }
1057
 
1058
    xw.writeEndElement(); /* Item */
1059
 
1060
    xw.writeElementString('ErrorLanguage', 'en_US');
1061
    xw.writeElementString('Version', configeBayTradingVersion);
1062
    xw.writeElementString('WarningLevel', configWarningLevel);
1063
 
1064
    xw.writeEndElement(); /* xmlrequest */
1065
    xw.writeEndDocument();
1066
 
1067
    xhr.open('POST', configProxyUrl, true);
1068
    xhr.setRequestHeader('Content-Type', 'text/xml');
1069
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
1070
    xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
1071
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
1072
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
1073
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
1074
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
1075
    xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
1076
 
1077
    return true;
1078
}
1079
 
1080
function connected() {
1081
    var x;
1082
 
1083
    eBayAuthTokenFlag = true;
1084
    document.getElementById("connected").innerHTML += " (Connected)";
1085
 
1086
    x = document.getElementById("login");
1087
    x.className = x.className.replace(" w3-show", "");
1088
 
1089
    x = document.getElementById("results");
1090
    x.innerHTML = "";
1091
    x.className = x.className.replace(" w3-show", "");
1092
}
1093
 
1094
    </script>
17 - 1095
    <script>includeHTML();</script>
2 - 1096
 
1097
</body>
1098
</html>