Subversion Repositories munaweb

Rev

Rev 3 | Go to most recent revision | Details | 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 Listing Promotion</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
    <script src="js/jquery.js"></script>
12
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
13
    <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
14
    <link rel="stylesheet" href="css/style.css">
15
    <script src="js/XMLWriter.js"></script>
16
    <script src="js/vkbeautify.js"></script>
17
    <script src="js/lodash.min.js"></script>
18
    <script src="js/XMLparse.js"></script>
19
    <script src="js/moment.js"></script>
20
    <script src="js/moment-timezone.js"></script>
21
    <script src="js/muna-tools.js"></script>
22
</head>
23
 
24
<body onload="return initConfig();">
25
    <div class="w3-main">
26
        <div class="w3-container w3-padding w3-margin w3-card-4">
27
            <div class="w3-container w3-gray" style="height:100px">
28
                <img class="w3-image" src="images/MUNA%20-%20Logo%20100x100.png" alt="MUNA Trading Logo" style="height:100px">
29
                <p id="connected" class="w3-xxlarge w3-right">eBay Listing Promotion
30
                    <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" />
31
               	</p>
32
            </div>
33
 
34
            <div class="w3-row">
35
                <div>
36
                    <form id="searchForm" class="w3-container w3-light-grey w3-padding w3-small" onsubmit="return getListingsForPromote();">
37
                        <div class="w3-container w3-card-2 w3-cell w3-padding">
38
                        	<textarea id="bearer" rows="4" cols="80"></textarea>
39
                            <input id="promoteButton" type="button" class="w3-btn w3-large w3-red w3-margin w3-round-large w3-ripple" onclick="getListingsForPromote();" value="Promote" />
40
                        </div>
41
                    </form>
42
                </div>
43
                <div id="progressBarDiv" class="w3-container w3-padding w3-margin w3-card-4 w3-hide">
44
                  	<h2 id="progressBarHeader"></h2>
45
                    <div class="w3-light-grey">
46
                        <div id="progressBar" class="w3-container w3-green w3-center" style="width:0%">0%</div>
47
                    </div>
48
                </div>
49
                <div id="results" class="w3-container w3-padding w3-card-4 w3-hide"></div>
50
                <div id="logging" class="w3-container w3-padding"></div>
51
            </div>
52
        </div>
53
 
54
        <footer class="w3-container w3-center w3-border-top w3-margin">
55
            Copyright &#169; 2018 MUNA Trading. All rights reserved.
56
        </footer>
57
 
58
    </div>
59
 
60
    <script>
61
 
62
// Config
63
var configCampaignId = '10477406018';
64
 
65
var pagesToProcess = 0;
66
var pagesProcessed = 0;
67
var html = [];
68
 
69
// Initialize Configuration Variables
70
function initConfig() {
71
    eBayAuthToken = readCookie();
72
    if (eBayAuthToken.length > 0) {
73
        connected();
74
    }
75
 
76
    if (eBayAuthTokenFlag === false) {
77
        var x = document.getElementById("login");
78
        if (x.className.indexOf("w3-show") == -1) {
79
            x.className += " w3-show";
80
        }
81
    }
82
}
83
 
84
function requireNewLogin() {
85
    // dummy
86
}
87
 
88
function connected() {
89
    var x;
90
 
91
    eBayAuthTokenFlag = true;
92
    document.getElementById("connected").innerHTML += " (Connected)";
93
 
94
    x = document.getElementById("promoteButton");
95
    x.className = x.className.replace(" w3-red", " w3-black");
96
 
97
    x = document.getElementById("login");
98
    x.className = x.className.replace(" w3-show", "");
99
 
100
    x = document.getElementById("results");
101
    x.innerHTML = "";
102
    x.className = x.className.replace(" w3-show", "");
103
    x.className = x.className.replace("process-errors", "");
104
}
105
 
106
function getListingsForPromote() {
107
    var x;
108
 
109
    if (eBayAuthTokenFlag === false) {
110
        return;
111
    }
112
 
113
    userAccessToken = document.getElementById("bearer").value;
114
    if (userAccessToken.length < 1) {
115
        return;
116
    }
117
 
118
    document.getElementById("logging").innerHTML = '';
119
 
120
    x = document.getElementById("results");
121
    if (x.className.indexOf("w3-show") == -1) {
122
        x.className += " w3-show";
123
    }
124
    x.innerHTML = '<p><strong>Retrieving Listings...</strong></p>';
125
    x.className = x.className.replace("process-errors", "");
126
 
127
    pagesToProcess = 1;
128
    pagesProcessed = 0;
129
    initProgressBar("Retrieving Listings...");
130
    eBaySearch(1);
131
 
132
    function checkpagesToProcess() {
133
        if (pagesToProcess > 0) {
134
            window.setTimeout(checkpagesToProcess, 300); // wait 100 milliseconds
135
        } else {
136
            endProgressBar();
137
            document.getElementById("results").innerHTML += '<p><strong>Sorting / Cleaning List...</strong></p>';
138
            sortTable();
139
            removeDuplicateRows($('#promoteTable'));
140
            processCurrentAds();
141
        }
142
    }
143
 
144
    checkpagesToProcess();
145
}
146
 
147
function processCurrentAds() {
148
    adsToRead = 1;
149
    getCurrentAds(1);
150
 
151
    function checkAdsToRead() {
152
        if (adsToRead > 0) {
153
            window.setTimeout(checkAdsToRead, 100); // wait 100 milliseconds
154
        } else {
155
            updateAds();
156
        }
157
    }
158
 
159
    checkAdsToRead();
160
}
161
 
162
function updateAds() {
163
    var i = 1;
164
    var pt = document.getElementById("promoteTable");
165
    var x;
166
    var updateList = [];
167
    var addList = [];
168
    var entry;
169
    var maxAds = 500;
170
 
171
    adsToUpdate = 0;
172
 
173
    for (i = 1; i < pt.rows.length; i++) {
174
        if (pt.rows[i].cells[1].innerHTML != pt.rows[i].cells[3].innerHTML) {
175
            entry = '{"bidPercentage":"' + pt.rows[i].cells[1].innerHTML + '","listingId" : "' + pt.rows[i].cells[0].innerHTML + '"}';
176
            if (pt.rows[i].cells[2].innerHTML.length > 0) {
177
                if (updateList.indexOf(entry) == -1) {
178
                    updateList.push(entry);
179
                }
180
            } else {
181
                if (addList.indexOf(entry) == -1) {
182
                    addList.push(entry);
183
                }
184
            }
185
        }
186
    }
187
 
188
    for (i = 0; (i * maxAds) < updateList.length; i++) {
189
        ++adsToUpdate;
190
        updateAd(1, updateList.slice(i * maxAds, (i + 1) * maxAds));
191
    }
192
 
193
    for (i = 0; (i * maxAds) < addList.length; i++) {
194
        ++adsToUpdate;
195
        updateAd(0, addList.slice(i * maxAds, (i + 1) * maxAds));
196
    }
197
 
198
    function checkAdsToUpdate() {
199
        if (adsToUpdate > 0) {
200
            window.setTimeout(checkAdsToUpdate, 100); // wait 100 milliseconds
201
        } else {
202
            x = document.getElementById("results");
203
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';
204
            if (!x.className.includes("process-errors")) {
205
                setTimeout(function() {
206
                    x.className = x.className.replace(" w3-show", "");
207
                }, 3000);
208
            }
209
        }
210
    }
211
 
212
    checkAdsToUpdate();
213
}
214
 
215
function getCurrentAds(pageNumber) {
216
    var i;
217
    var response;
218
    var limit = 500;
219
    url = configeBayAdCampaign;
220
    url += configCampaignId;
221
    url += '/ad?';
222
    url += 'offset=';
223
    url += (pageNumber - 1) * limit;
224
    url += '&limit=';
225
    url += limit;
226
 
227
    var xhttp = new XMLHttpRequest();
228
 
229
    xhttp.onreadystatechange = function() {
230
        if (this.readyState == 4) {
231
            if (this.status == 200) {
232
                response = JSON.parse(this.responseText);
233
 
234
                for (i = 0; i < response.ads.length; i++) {
235
                    itemId = response.ads[i].listingId;
236
                    if (document.getElementById('AdId' + itemId) !== null) {
237
                        document.getElementById('AdId' + itemId).innerHTML = response.ads[i].adId;
238
                        document.getElementById('CurrentRate' + itemId).innerHTML = response.ads[i].bidPercentage;
239
                    }
240
                }
241
 
242
                if (Number(response.total) > (pageNumber * limit)) {
243
                    ++adsToRead;
244
                    document.getElementById("results").innerHTML += '<p><strong>Retrieving Ads (' + pageNumber + '/' + Number((response.total / limit) + 1).toFixed(0) + ')</strong></p>';
245
                    getCurrentAds(pageNumber + 1);
246
                }
247
            }
248
 
249
            --adsToRead;
250
        }
251
    };
252
 
253
    xhttp.open("GET", configProxyUrl, true);
254
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
255
    xhttp.setRequestHeader('X-Authorization', 'Bearer ' + userAccessToken);
256
    xhttp.send();
257
}
258
 
259
function updateAd(flag, list) {
260
    var xhttp;
261
    var json;
262
    var i;
263
    var obj;
264
 
265
    if (list.length === 0) {
266
        return;
267
    }
268
 
269
    json = '{"requests":[' + list.join(',') + ']}';
270
 
271
    if (flag) {
272
        url = configeBayAdCampaign;
273
        url += configCampaignId;
274
        url += '/bulk_update_ads_bid_by_listing_id';
275
 
276
        xhttp = new XMLHttpRequest();
277
 
278
        xhttp.onreadystatechange = function() {
279
            if (this.readyState == 4) {
280
                obj = JSON.parse(this.responseText);
281
                if (this.status == 200 || this.status == 207) {
282
                    for (i = 0; i < obj.responses.length; i++) {
283
                        if (Number(obj.responses[i].statusCode) == 200) {
284
                            document.getElementById('AdId' + obj.responses[i].listingId).innerHTML = obj.responses[i].adId;
285
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Updated';
286
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'green';
287
                        } else {
288
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Update Failed (';
289
                            if (obj.responses[i].errors !== undefined) {
290
                                document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += obj.responses[i].errors[0].message;
291
                            } else if (obj.responses[i].statusCode !== undefined) {
292
                                document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += obj.responses[i].statusCode;
293
                            }
294
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += ')';
295
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'red';
296
                        }
297
                    }
298
                } else {
299
                    var x = document.getElementById("results");
300
                    x.className += " process-errors";
301
                    x.innerHTML += '<p class="w3-red">Bulk Update Ads: <strong>' + this.status + '</strong></p>';
302
                }
303
 
304
                --adsToRead;
305
            }
306
        };
307
 
308
        xhttp.open("POST", configProxyUrl, true);
309
        xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
310
        xhttp.setRequestHeader('X-Authorization', 'Bearer ' + userAccessToken);
311
        xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
312
        xhttp.send(json);
313
 
314
    } else {
315
        url = configeBayAdCampaign;
316
        url += configCampaignId;
317
        url += '/bulk_create_ads_by_listing_id';
318
 
319
        xhttp = new XMLHttpRequest();
320
 
321
        xhttp.onreadystatechange = function() {
322
            if (this.readyState == 4) {
323
                obj = JSON.parse(this.responseText);
324
                if (this.status == 200 || this.status == 207) {
325
                    for (i = 0; i < obj.responses.length; i++) {
326
                        if (Number(obj.responses[i].statusCode) == 201) {
327
                            document.getElementById('AdId' + obj.responses[i].listingId).innerHTML = obj.responses[i].adId;
328
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Added';
329
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'green';
330
                        } else {
331
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Add Failed (' + obj.responses[i].errors[0].message + ')';
332
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'red';
333
                        }
334
                    }
335
                } else {
336
                    var x = document.getElementById("results");
337
                    x.className += " process-errors";
338
                    x.innerHTML += '<p class="w3-red">Bulk Create Ads: <strong>' + this.status + '</strong></p>';
339
                }
340
 
341
                --adsToRead;
342
            }
343
        };
344
 
345
        xhttp.open("POST", configProxyUrl, true);
346
        xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
347
        xhttp.setRequestHeader('X-Authorization', 'Bearer ' + userAccessToken);
348
        xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
349
        xhttp.send(json);
350
    }
351
 
352
    --adsToUpdate;
353
}
354
 
355
 
356
// Build an HTML table to display search results
357
function eBaySearch(pageNo) {
358
    var i;
359
    var xml;
360
 
361
    if (eBayAuthTokenFlag === false) {
362
        return;
363
    }
364
 
365
    var xw = new XMLWriter('UTF-8', '1.0');
366
    var xhr = new XMLHttpRequest();
367
 
368
    if (!createAddXMLSearch(xw, xhr, 'GetSellerList', pageNo)) {
369
        return;
370
    }
371
 
372
    xml = xw.flush();
373
    xw.close();
374
    //window.alert(vkbeautify.xml(xml));
375
 
376
    xhr.onload = function() {
377
        var obj = XMLparse(xhr.responseXML);
378
        //window.alert(JSON.stringify(obj));
379
        //window.alert(vkbeautify.xml(xhr.responseText));
380
 
381
        var returnCode = obj.Ack;
382
 
383
        var x = document.getElementById("results");
384
 
385
        if (returnCode == 'Success') {
386
            createTable(obj.ItemArray, pageNo, Number(obj.PaginationResult.TotalNumberOfPages));
387
 
388
            if (Number(obj.PaginationResult.TotalNumberOfPages) > pageNo) {
389
                maxPagesToProcess = Number(obj.PaginationResult.TotalNumberOfPages);
390
                ++pagesToProcess;
391
                eBaySearch(pageNo + 1);
392
            }
393
 
394
            updateProgressBar(maxPagesToProcess, pagesProcessed);
395
        } else {
396
            x.className += " process-errors";
397
            x.innerHTML += '<p class="w3-red"><strong>' + returnCode + ':</strong></p>';
398
            var errors = obj.Errors;
399
            x.innerHTML += "<p>";
400
            if (errors.length > 0) {
401
                for (i = 0; i < errors.length; i++) {
402
                    x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
403
                }
404
            } else {
405
                x.innerHTML += obj.Errors.SeverityCode + " (" + obj.Errors.ErrorCode + "): " + escapeHtml(obj.Errors.LongMessage) + "<br/>";
406
            }
407
            x.innerHTML += "</p>";
408
        }
409
 
410
        --pagesToProcess;
411
        ++pagesProcessed;
412
 
413
        document.getElementById("logging").innerHTML = html.join('');
414
        updateProgressBar(maxPagesToProcess, pagesProcessed);
415
    };
416
 
417
    xhr.send(xml);
418
}
419
 
420
function createAddXMLSearch(xw, xhr, callname, pageNo) {
421
    var startDate = moment(moment().subtract(31, "days").format('YYYY-MM-DD') + " 00:00:00", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
422
    var todayDate = moment(moment().format('YYYY-MM-DD') + " 23:59:59", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
423
    var endDate = moment(moment().add(31, "days").format('YYYY-MM-DD') + " 00:00:00", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
424
 
425
    xw.writeStartDocument();
426
    xw.writeStartElement(callname + "Request");
427
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
428
 
429
    xw.writeStartElement('RequesterCredentials');
430
    xw.writeElementString('eBayAuthToken', eBayAuthToken);
431
    xw.writeEndElement(); /* RequesterCredentials */
432
 
433
    xw.writeElementString('GranularityLevel', 'Coarse');
434
    xw.writeElementString('StartTimeFrom', startDate);
435
    xw.writeElementString('StartTimeTo', todayDate);
436
    xw.writeElementString('EndTimeFrom', todayDate);
437
    xw.writeElementString('EndTimeTo', endDate);
438
    xw.writeElementString('OutputSelector', 'ItemArray.Item.ItemID');
439
    xw.writeElementString('OutputSelector', 'ItemArray.Item.ListingType');
440
    xw.writeElementString('OutputSelector', 'PaginationResult');
441
    xw.writeElementString('OutputSelector', 'ItemArray.Item.SellingStatus.ConvertedCurrentPrice');
442
    xw.writeStartElement('Pagination');
443
    xw.writeElementString('EntriesPerPage', '200');
444
    xw.writeElementString('PageNumber', '' + pageNo);
445
    xw.writeEndElement(); /* Pagination*/
446
 
447
    xw.writeElementString('ErrorLanguage', 'en_US');
448
    xw.writeElementString('Version', configeBayTradingVersion);
449
    xw.writeElementString('WarningLevel', configWarningLevel);
450
 
451
    xw.writeEndElement(); /* xmlrequest */
452
    xw.writeEndDocument();
453
 
454
    xhr.open('POST', configProxyUrl, true);
455
    xhr.setRequestHeader('Content-Type', 'text/xml');
456
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
457
    xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
458
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
459
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
460
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
461
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
462
    xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
463
 
464
    return true;
465
}
466
 
467
/* function _cb_findItemsAdvanced(root) { // xxxxx
468
	// Error Handling
469
	var response = root.findItemsAdvancedResponse[0];
470
	var ack = response.ack;
471
	if (ack != 'Success') {
472
		printeBayAPIError(response);
473
 
474
		if (ack == 'Failure' || ack == 'PartialFailure') {
475
			--pagesToProcess;
476
			return;
477
		}
478
	}
479
 
480
	createTable(response.searchResult[0].item || [], Number(response.paginationOutput[0].pageNumber), Number(response.paginationOutput[0].totalPages));
481
 
482
	if (Number(response.paginationOutput[0].totalPages) > Number(response.paginationOutput[0].pageNumber)) {
483
		++pagesToProcess;
484
		eBaySearch(Number(response.paginationOutput[0].pageNumber) + 1);
485
	}
486
 
487
	document.getElementById("logging").innerHTML = html.join('');
488
	--pagesToProcess;
489
} // End _cb_findItemsAdvanced() function
490
*/
491
 
492
function createTable(obj, pageNumber, totalPages) {
493
    var currentPrice;
494
    var adRate;
495
 
496
    if (pageNumber == 1) {
497
        document.getElementById("logging").innerHTML = '';
498
        html = [];
499
 
500
        html.push('<h3>Listing Promotions</h3>');
501
        html.push('<div class="w3-responsive">');
502
        html.push('<table id="promoteTable" class="w3-table-all w3-hoverable">');
503
        html.push('<thead>');
504
        html.push('<tr>');
505
 
506
        html.push(tableHeader('Item ID'));
507
        html.push(tableHeader('New Ad Rate'));
508
        html.push(tableHeader('Ad Id'));
509
        html.push(tableHeader('Current Ad Rate'));
510
        html.push(tableHeader('Create/Update Status'));
511
 
512
        html.push('</tr>');
513
        html.push('</thead>');
514
        html.push('<tbody>');
515
    }
516
 
517
    for (var entry = 0; entry < obj.length; entry++) {
518
 
519
        if (obj[entry].ListingType == 'Chinese') {
520
            continue;
521
        }
522
 
523
        currentPrice = Number(obj[entry].SellingStatus.text).toFixed(2);
524
 
525
        // minimum ad rate is 1.00%
526
        if (currentPrice > 99.99) {
527
            adRate = 2.0;
528
        } else if (currentPrice > 49.99) {
529
            adRate = 2.7;
530
        } else if (currentPrice > 29.99) {
531
            adRate = 3.0;
532
        } else if (currentPrice > 19.99) {
533
            adRate = 3.2;
534
        } else if (currentPrice > 14.99) {
535
            adRate = 3.5;
536
        } else if (currentPrice > 9.99) {
537
            adRate = 3.7;
538
        } else if (currentPrice > 4.99) {
539
            adRate = 4.0;
540
        } else if (currentPrice > 3.99) {
541
            adRate = 4.2;
542
        } else {
543
            continue;
544
        }
545
 
546
        html.push('<tr>');
547
 
548
        html.push(tableCell(obj[entry].ItemID));
549
        html.push(tableCell(Number(adRate).toFixed(1)));
550
        html.push(tableCellLabel('AdId' + obj[entry].ItemID));
551
        html.push(tableCellLabel('CurrentRate' + obj[entry].ItemID));
552
        html.push(tableCellLabel('UpdateStatus' + obj[entry].ItemID));
553
 
554
        html.push('</tr>');
555
    }
556
 
557
    if (pageNumber == totalPages) {
558
        html.push('</tbody>');
559
        html.push('</table>');
560
        html.push('</div>');
561
    }
562
}
563
 
564
function sortTable() {
565
    var i;
566
    var tbl = document.getElementById("promoteTable").tBodies[0];
567
    var store = [];
568
    for (i = 0, len = tbl.rows.length; i < len; i++) {
569
        var row = tbl.rows[i];
570
        var sortnr = parseFloat(row.cells[0].textContent || row.cells[0].innerText);
571
        if (!isNaN(sortnr)) store.push([sortnr, row]);
572
    }
573
    store.sort(function(x, y) {
574
        return x[0] - y[0];
575
    });
576
    for (i = 0, len = store.length; i < len; i++) {
577
        tbl.appendChild(store[i][1]);
578
    }
579
    store = null;
580
}
581
 
582
    </script>
583
 
584
</body>
585
</html>