Subversion Repositories munaweb

Rev

Rev 156 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<!DOCTYPE html>
<html lang="en">

<head>
    <title>eBay Listing Promotion</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    <link rel="icon" href="favicon.ico" type="image/x-icon">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="js/XMLWriter.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>
    <link rel="stylesheet" href="css/style.css">
    <script src="js/muna-tools.js"></script>
</head>

<body onload="return initConfig();">
    <div>
        <div>
            <div class="container-fluid bg-secondary">
                <div class="clearfix">
                    <img class="img-fluid float-right" src="images/MUNA%20-%20Logo%20100x100.png" alt="MUNA Trading Logo" />
                    <h1 id="connected">eBay Listing Promotion
                    <input id="login" type="button" class="btn bg-success mb-2 w3-hide" onclick="eBayLogin();" value="Login" /></h1>
                </div>
            </div>

            <div class="border col">
                <div>
                    <form id="searchForm" class="container-fluid bg-light" onsubmit="return getListingsForPromote();">
                        <input id="promoteButton" type="button" class="btn btn-danger" onclick="getListingsForPromote();" value="Promote" />
                    </form>
                </div>
                <div class="modal" id="progressBarDiv">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h4 id="progressBarHeader"></h4>
                            </div>
                            <div class="modal-body">
                                <div class="progress">
                                    <div id="progressBar" class="progress-bar" style="width:0%">0%</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div id="results" class="border bg-info w3-hide"></div>
                <div id="logging"></div>
            </div>
        </div>

        <footer class="container-fluid text-center border border-bottom-0 border-left-0 border-right-0">
            <div w3-include-html="php/footer.php"></div>
        </footer>

    </div>

    <script>

// Config
var configCampaignId = '10477406018';
var accessToken = '';
var refreshToken = '';

var pagesToProcess = 0;
var maxPagesToProcess = 0;
var pagesProcessed = 0;
var html = [];

// Initialize Configuration Variables
function initConfig() {
    eBayAuthToken = readCookie();
    if (eBayAuthToken.length > 0) {
        connected();
    }

    if (eBayAuthTokenFlag === false) {
        var x = document.getElementById("login");
        if (x.className.indexOf("w3-show") == -1) {
            x.className += " w3-show";
        }
    }
    
    getOAuthToken();
}

function requireNewLogin() {
    // dummy
}

function connected() {
    var x;

    eBayAuthTokenFlag = true;
    document.getElementById("connected").innerHTML += " (Connected)";

    x = document.getElementById("promoteButton");
    x.className = x.className.replace(" btn-danger", " btn-dark");

    x = document.getElementById("login");
    x.className = x.className.replace(" w3-show", "");

    x = document.getElementById("results");
    x.innerHTML = "";
    x.className = x.className.replace(" w3-show", "");
    x.className = x.className.replace("process-errors", "");
}

function getListingsForPromote() {
    var x;

    if (eBayAuthTokenFlag === false) {
        return;
    }

//    if (accessToken.length < 1) {
//        getOAuthToken();
//    } else if (refreshToken.length > 0) {
//        refreshApplicationToken(refreshToken);
//    }

    if (accessToken.length < 1) {
        return;
    }

    document.getElementById("logging").innerHTML = '';

    x = document.getElementById("results");
    if (x.className.indexOf("w3-show") == -1) {
        x.className += " w3-show";
    }
    x.innerHTML = '<p><strong>Retrieving Listings...</strong></p>';
    x.className = x.className.replace("process-errors", "");

    pagesToProcess = 1;
    maxPagesToProcess = 0;
    pagesProcessed = 0;
    initProgressBar("Retrieving Listings...");
    eBaySearch(1);

    function checkpagesToProcess() {
        if (pagesToProcess > 0) {
            window.setTimeout(checkpagesToProcess, 300); // wait 100 milliseconds
        } else {
            endProgressBar();
            processCurrentAds();
        }
    }

    checkpagesToProcess();
}

function processCurrentAds() {
    adsToRead = 1;
    getCurrentAds(1);

    function checkAdsToRead() {
        if (adsToRead > 0) {
            window.setTimeout(checkAdsToRead, 100); // wait 100 milliseconds
        } else {
            updateAds();
        }
    }

    checkAdsToRead();
}

function updateAds() {
    var i = 1;
    var pt = document.getElementById("promoteTable");
    var x;
    var updateList = [];
    var addList = [];
    var entry;
    var maxAds = 500;

    adsToUpdate = 0;

    for (i = 1; i < pt.rows.length; i++) {
        if (pt.rows[i].cells[1].innerHTML != pt.rows[i].cells[3].innerHTML) {
            entry = '{"bidPercentage":"' + pt.rows[i].cells[1].innerHTML + '","listingId" : "' + pt.rows[i].cells[0].innerHTML + '"}';
            if (pt.rows[i].cells[2].innerHTML.length > 0) {
                if (updateList.indexOf(entry) == -1) {
                    updateList.push(entry);
                }
            } else {
                if (addList.indexOf(entry) == -1) {
                    addList.push(entry);
                }
            }
        }
    }

    for (i = 0; (i * maxAds) < updateList.length; i++) {
        ++adsToUpdate;
        updateAd(1, updateList.slice(i * maxAds, (i + 1) * maxAds));
    }

    for (i = 0; (i * maxAds) < addList.length; i++) {
        ++adsToUpdate;
        updateAd(0, addList.slice(i * maxAds, (i + 1) * maxAds));
    }

    function checkAdsToUpdate() {
        if (adsToUpdate > 0) {
            window.setTimeout(checkAdsToUpdate, 100); // wait 100 milliseconds
        } else {
            x = document.getElementById("results");
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';
            if (!x.className.includes("process-errors")) {
                setTimeout(function() {
                    x.className = x.className.replace(" w3-show", "");
                }, 3000);
            }
        }
    }

    checkAdsToUpdate();
}

function getCurrentAds(pageNumber) {
    var i;
    var response;
    var limit = 500;
    url = configeBayAdCampaign;
    url += configCampaignId;
    url += '/ad?';
    url += 'offset=';
    url += (pageNumber - 1) * limit;
    url += '&limit=';
    url += limit;

    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
        if (this.readyState == 4) {
            if (this.status == 200) {
                response = JSON.parse(this.responseText);

                for (i = 0; i < response.ads.length; i++) {
                    itemId = response.ads[i].listingId;
                    if (document.getElementById('AdId' + itemId) !== null) {
                        document.getElementById('AdId' + itemId).innerHTML = response.ads[i].adId;
                        document.getElementById('CurrentRate' + itemId).innerHTML = response.ads[i].bidPercentage;
                    }
                }

                if (Number(response.total) > (pageNumber * limit)) {
                    ++adsToRead;
                    document.getElementById("results").innerHTML += '<p><strong>Retrieving Ads (' + pageNumber + '/' + Number((response.total / limit) + 1).toFixed(0) + ')</strong></p>';
                    getCurrentAds(pageNumber + 1);
                }
            }

            --adsToRead;
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
    xhttp.setRequestHeader('X-Authorization', 'Bearer ' + accessToken);
    xhttp.send();
}

function updateAd(flag, list) {
    var xhttp;
    var json;
    var i, j;
    var obj;
    var errors;

    if (list.length === 0) {
        return;
    }

    json = '{"requests":[' + list.join(',') + ']}';

    if (flag) {
        url = configeBayAdCampaign;
        url += configCampaignId;
        url += '/bulk_update_ads_bid_by_listing_id';

        xhttp = new XMLHttpRequest();

        xhttp.onreadystatechange = function() {
            if (this.readyState == 4) {
                obj = JSON.parse(this.responseText);
                if (this.status == 200 || this.status == 207) {
                    for (i = 0; i < obj.responses.length; i++) {
                        if (Number(obj.responses[i].statusCode) == 200) {
                            document.getElementById('AdId' + obj.responses[i].listingId).innerHTML = obj.responses[i].adId;
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Updated';
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'green';
                        } else {
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Update Failed (';
                            errors = getJsonArray(obj.responses[i].errors);
                            if (errors[0] !== undefined) {
                                document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += errors[0].message;
                            } else if (obj.responses[i].statusCode !== undefined) {
                                document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += " " + obj.responses[i].statusCode;
                            }
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += ')';
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'red';
                        }
                    }
                } else {
                    var x = document.getElementById("results");
                    x.className += " process-errors";
                    x.innerHTML += '<p class="text-danger">Bulk Update Ads: <strong>' + this.status + '</strong></p>';
                }

                --adsToRead;
            }
        };

        xhttp.open("POST", configProxyUrl, true);
        xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
        xhttp.setRequestHeader('X-Authorization', 'Bearer ' + accessToken);
        xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
        xhttp.send(json);

    } else {
        url = configeBayAdCampaign;
        url += configCampaignId;
        url += '/bulk_create_ads_by_listing_id';

        xhttp = new XMLHttpRequest();

        xhttp.onreadystatechange = function() {
            if (this.readyState == 4) {
                obj = JSON.parse(this.responseText);
                if (this.status == 200 || this.status == 207) {
                    for (i = 0; i < obj.responses.length; i++) {
                        if (Number(obj.responses[i].statusCode) == 201) {
                            document.getElementById('AdId' + obj.responses[i].listingId).innerHTML = obj.responses[i].adId;
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Added';
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'green';
                        } else {
                            errors = getJsonArray(obj.responses[i].errors);
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Add Failed (' + getJsonValue(errors[0].message) + ')';
                            document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'red';
                        }
                    }
                } else {
                    var x = document.getElementById("results");
                    x.className += " process-errors";
                    x.innerHTML += '<p class="text-danger">Bulk Create Ads: <strong>' + this.status + '</strong></p>';
                }

                --adsToRead;
            }
        };

        xhttp.open("POST", configProxyUrl, true);
        xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
        xhttp.setRequestHeader('X-Authorization', 'Bearer ' + accessToken);
        xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
        xhttp.send(json);
    }

    --adsToUpdate;
}


// Build an HTML table to display search results
function eBaySearch(pageNo) {
    var i;
    var xml;

    if (eBayAuthTokenFlag === false) {
        return;
    }

    var xw = new XMLWriter('UTF-8', '1.0');
    var xhr = new XMLHttpRequest();

    if (!createAddXMLSearch(xw, xhr, 'GetSellerList', pageNo)) {
        return;
    }

    xml = xw.flush();
    xw.close();

    xhr.onload = function() {
        var jsonObj = XMLparse(xhr.responseXML, false);
        var obj = jsonObj.GetSellerListResponse;
        var returnCode = obj.Ack;
        var str;

        var x = document.getElementById("results");

        if (returnCode == 'Success') {
            createTable(obj.ItemArray, pageNo, Number(obj.PaginationResult.TotalNumberOfPages));

            if (Number(obj.PaginationResult.TotalNumberOfPages) > pageNo) {
                maxPagesToProcess = Number(obj.PaginationResult.TotalNumberOfPages);
                ++pagesToProcess;
                eBaySearch(pageNo + 1);
            }

            updateProgressBar(maxPagesToProcess, pagesProcessed);
        } else {
            x.className += " process-errors";
            str = '<p class="text-danger"><strong>' + returnCode + ':</strong></p>';
            var errors = getJsonArray(obj.Errors);
            str += "<p>";
            for (i = 0; i < errors.length; i++) {
                str += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
            }
            str += "</p>";

            x.innerHTML += str;
        }

        --pagesToProcess;
        ++pagesProcessed;

        document.getElementById("logging").innerHTML = html.join('');
        updateProgressBar(maxPagesToProcess, pagesProcessed);
    };

    xhr.send(xml);
}

function createAddXMLSearch(xw, xhr, callname, pageNo) {
    var startDate = moment(moment().subtract(31, "days").format('YYYY-MM-DD') + " 00:00:00", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
    var todayDate = moment(moment().format('YYYY-MM-DD') + " 23:59:59", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
    var endDate = moment(moment().add(31, "days").format('YYYY-MM-DD') + " 00:00:00", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();

    xw.writeStartDocument();
    xw.writeStartElement(callname + "Request");
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');

    xw.writeStartElement('RequesterCredentials');
    xw.writeElementString('eBayAuthToken', eBayAuthToken);
    xw.writeEndElement(); /* RequesterCredentials */

    xw.writeElementString('DetailLevel', 'ItemReturnDescription');
    xw.writeElementString('StartTimeFrom', startDate);
    xw.writeElementString('StartTimeTo', todayDate);
    xw.writeElementString('EndTimeFrom', todayDate);
    xw.writeElementString('EndTimeTo', endDate);
    xw.writeElementString('OutputSelector', 'ItemArray.Item.ItemID');
    xw.writeElementString('OutputSelector', 'ItemArray.Item.ListingType');
    xw.writeElementString('OutputSelector', 'PaginationResult');
    xw.writeElementString('OutputSelector', 'ItemArray.Item.SellingStatus.ConvertedCurrentPrice');
    xw.writeStartElement('Pagination');
    xw.writeElementString('EntriesPerPage', '200');
    xw.writeElementString('PageNumber', '' + pageNo);
    xw.writeEndElement(); /* Pagination*/

    xw.writeElementString('ErrorLanguage', 'en_US');
    xw.writeElementString('Version', configeBayTradingVersion);
    xw.writeElementString('WarningLevel', configWarningLevel);

    xw.writeEndElement(); /* xmlrequest */
    xw.writeEndDocument();

    xhr.open('POST', configProxyUrl, true);
    xhr.setRequestHeader('Content-Type', 'text/xml');
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
    xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
    xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);

    return true;
}

function createTable(obj, pageNumber, totalPages) {
    var currentPrice;
    var adRate;

    if (pageNumber == 1) {
        document.getElementById("logging").innerHTML = '';
        html = [];

        html.push('<div class="border table-responsive">');
        html.push('<h3>Listing Promotions</h3>');
        html.push('<table id="promoteTable" class="table table-hover table-striped table-bordered small">');
        html.push('<thead class="thead-dark">');
        html.push('<tr>');

        html.push(tableHeader('Item ID'));
        html.push(tableHeader('New Ad Rate'));
        html.push(tableHeader('Ad Id'));
        html.push(tableHeader('Current Ad Rate'));
        html.push(tableHeader('Create/Update Status'));

        html.push('</tr>');
        html.push('</thead>');
        html.push('<tbody>');
    }

    for (var entry = 0; entry < obj.Item.length; entry++) {
        var item = obj.Item[entry];

        if (item.ListingType == 'Chinese') {
            continue;
        }

        currentPrice = Number(item.SellingStatus.ConvertedCurrentPrice.text).toFixed(2);

        // minimum ad rate is 1.00%
/*
        if (currentPrice > 99.99) {
            adRate = 2.0;
        } else if (currentPrice > 49.99) {
            adRate = 2.7;
        } else if (currentPrice > 29.99) {
            adRate = 3.0;
        } else if (currentPrice > 19.99) {
            adRate = 3.2;
        } else if (currentPrice > 14.99) {
            adRate = 3.5;
        } else if (currentPrice > 9.99) {
            adRate = 3.7;
        } else if (currentPrice > 4.99) {
            adRate = 4.0;
        } else if (currentPrice > 3.99) {
            adRate = 4.2;
        } else {
            continue;
        }
*/

        adRate = 3.0;

        html.push('<tr>');

        html.push(tableCell(item.ItemID));
        html.push(tableCell(Number(adRate).toFixed(1)));
        html.push(tableCellLabel('AdId' + item.ItemID));
        html.push(tableCellLabel('CurrentRate' + item.ItemID));
        html.push(tableCellLabel('UpdateStatus' + item.ItemID));

        html.push('</tr>');
    }

    if (pageNumber == totalPages) {
        html.push('</tbody>');
        html.push('</table>');
        html.push('</div>');
    }
}

function getOAuthToken() {
    var code = "";

        var win = window.open(configeBayLoginUrl, "eBay OAUTH", "");

        var pollTimer = window.setInterval(function() {
                if (win.closed !== false) {
                        window.clearInterval(pollTimer);
                        getApplicationToken(code);
                } else {
                    if (code === null || code.length === 0) {
                try {
                  code = getUrlParameter(win, 'code');
                } catch(err) {
                  // empty
                }
                    }
                }
        }, 200);

}

function getApplicationToken(code) {
    var param;

    param = 'grant_type=authorization_code';
    param += '&code=' + code;
    param += '&redirect_uri=' + configRuName;

    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
        if (this.readyState == 4) {
            if (this.status == 200) {
                response = JSON.parse(this.responseText);

                accessToken = getJsonValue(response.access_token);
                refreshToken = getJsonValue(response.refresh_token);
            }
        }
    };

    xhttp.open("POST", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", configOauthTokenUrl);
    xhttp.setRequestHeader('X-Authorization', 'Basic XxXAuthorization');
    xhttp.setRequestHeader('X-DECODE-PARAMS', '1');
    xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhttp.send(param);
}

function refreshApplicationToken(code) {
    var param;

    param = 'grant_type=refresh_token';
    param += '&refresh_token=' + code;
    param += '&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.marketing';

    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
        if (this.readyState == 4) {
            if (this.status == 200) {
                response = JSON.parse(this.responseText);

                accessToken = getJsonValue(response.access_token);
                refreshToken = getJsonValue(response.refresh_token);
            }
        }
    };

    xhttp.open("POST", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", configOauthTokenUrl);
    xhttp.setRequestHeader('X-Authorization', 'Basic XxXAuthorization');
    xhttp.setRequestHeader('X-DECODE-PARAMS', '1');
    xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhttp.send(param);
}
    </script>
    <script>includeHTML();</script>

</body>
</html>