Subversion Repositories munaweb

Rev

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

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

<head>
    <title>Order Reports</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">Order Reports
                    <input id="login" type="button" class="btn bg-success mb-2 w3-hide" onclick="eBayLogin();" value="Login" /></h1>
                </div>
            </div>

            <div class="border">
                <form id="searchForm" class="container-fluid bg-light" onsubmit="return getOrders();">
                    <div class="row">
                    <div class="col border">
                        <h4>Date Range</h4>
                            <div class="input-group mb-3">
                              <div class="input-group-prepend">
                                <span class="input-group-text bg-light"> &#9655;</span>
                              </div>
                              <input type="date" class="form-control" id="startDate" name="startDate" required>
                            </div>
                            <div class="input-group">
                              <div class="input-group-prepend">
                                <span class="input-group-text bg-light"> &#9665;</span>
                              </div>
                              <input type="date" class="form-control" id="endDate" name="endDate" required>
                            </div>
                    </div>
                    <div class="col border">
                        <h4>Report Type</h4>
                        <div class="form-check">
                            <label for="shippingList">
                                <input id="shippingList" class="form-check-input" type="radio" name="rptType" value="shippingList" checked>Awaiting Shipment
                            </label>
                        </div>
                        <div class="form-check">
                            <label for="orderList">
                                <input id="orderList" class="form-check-input" type="radio" name="rptType" value="orderList">Orders
                            </label>
                        </div>
                        <div class="form-check">
                            <label for="feeList">
                                <input id="feeList" class="form-check-input" type="radio" name="rptType" value="feeList">eBay Fees and Credits
                            </label>
                        </div>
                        <div class="form-check">
                            <label for="cancelReturnList">
                                <input id="cancelReturnList" class="form-check-input" type="radio" name="rptType" value="cancelReturnList">eBay Cancellations/Returns
                            </label>
                        </div>
                        <div class="form-check">
                            <label for="trackingList">
                                <input id="trackingList" class="form-check-input" type="radio" name="rptType" value="trackingList">Tracking Status
                            </label>
                        </div>
                        <div class="form-check">
                            <label for="customerList">
                                <input id="customerList" class="form-check-input" type="radio" name="rptType" value="customerList">eBay Customer Export
                            </label>
                        </div>

                        <input id="printButton" type="button" class="btn btn-dark float-right mx-2 w3-hide" onclick="printData();" value="Print" />
                        <input id="dlOrderListButton" type="button" class="btn btn-dark float-right mx-2 w3-hide" onclick="exportTableToCSV('orderTable', 'orders.csv');" value="CSV" />
                        <input id="dlFeeListButton" type="button" class="btn btn-dark float-right mx-2 w3-hide" onclick="exportTableToCSV('feeTable', 'fees.csv');" value="CSV" />
                        <input id="dlCancelReturnListButton" type="button" class="btn btn-dark float-right mx-2 w3-hide" onclick="exportTableToCSV('cancelReturnTable', 'returns.csv');" value="CSV" />
                        <input id="dlCustomerListButton" type="button" class="btn btn-dark float-right mx-2 w3-hide" onclick="exportTableToCSV('customerTable', 'customers.csv');" value="CSV" />
                        <input id="startButton" type="button" class="btn btn-danger float-right mx-2" onclick="getOrders();" value="Start" />
                    </div>
                    <div id="summary" class="col border"></div>
                    </div>
                </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="printTable">
                <div id="logging"></div>
            </div>
            <div id="modals"></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>

// Globals
var pagesToProcess = 0;
var pagesProcessed = 0;
var maxPagesToProcess = 0;
var shippingsToProcess = 0;
var shippingsProcessed = 0;
var thumbnailsToProcess = 0;
var thumbnailsProcessed = 0;
var maxThumbnailsToProcess = 0;
var trackingNumbersToProcess = 0;
var trackingNumbersProcessed = 0;
var maxTrackingNumbersToProcess = 0;
var html = [];
var url;
var trackingList = [];
var trackingListDedupe = [];

var itemsSold;
var grossSales;
var shippingRcvd;
var returnCost;
var shippingCost;
var eBayFees;
var PayPalFees;
var totalAmount;

// 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";
        }
    }

    var currentDate = moment();
    var weekDayName =  moment().format('dddd');
    var yesterday = moment().subtract((weekDayName == "Monday" ? 2 : 1), "days");

    x = document.getElementById("startDate");
    if (x.value.length < 1) {
        x.value = yesterday.format('YYYY-MM-DD');
    }

    x = document.getElementById("endDate");
    if (x.value.length < 1) {
        x.value = currentDate.format('YYYY-MM-DD');
    }
}

function requireNewLogin() {
    // dummy
}

function getOrders() {
    var x;

    itemsSold = 0;
    grossSales = 0.0;
    shippingRcvd = 0.0;
    returnCost = 0.0;
    shippingCost = 0.0;
    eBayFees = 0.0;
    PayPalFees = 0.0;

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

    var sDate = moment(document.getElementById("startDate").value, 'YYYY-MM-DD', true);
    var eDate = moment(document.getElementById("endDate").value, 'YYYY-MM-DD', true);

    if (!sDate.isValid()) {
        document.getElementById("startDate").value = '';
        return;
    }

    if (!eDate.isValid()) {
        document.getElementById("endDate").value = '';
        return;
    }

    if (moment(document.getElementById("startDate").value).isAfter(document.getElementById("endDate").value, 'day')) {
        document.getElementById("endDate").value = '';
        return;
    }

    x = document.getElementById("printButton");
    x.className = x.className.replace(" w3-show", "");
    x = document.getElementById("dlOrderListButton");
    x.className = x.className.replace(" w3-show", "");
    x = document.getElementById("dlFeeListButton");
    x.className = x.className.replace(" w3-show", "");
    x = document.getElementById("dlCancelReturnListButton");
    x.className = x.className.replace(" w3-show", "");
    x = document.getElementById("dlCustomerListButton");
    x.className = x.className.replace(" w3-show", "");

    x = document.getElementById("results");
    if (x.className.indexOf("w3-show") == -1) {
        x.className += " w3-show";
    }

    pagesToProcess = 1;
    pagesProcessed = 0;
    maxPagesToProcess = 1;

    if (getRadioValue('rptType') == 'feeList') {
        document.getElementById("results").innerHTML = '<p><strong>Retrieving Fees and Credits...</strong></p>';
        initProgressBar("Retrieving eBay Fees and Credits...");

        retrieveFees(1);
    } else if (getRadioValue('rptType') == 'cancelReturnList') {
        document.getElementById("results").innerHTML = '<p><strong>Retrieving Cancellations and Returns...</strong></p>';
        initProgressBar("Retrieving Returns...");

        retrieveCancelReturn(1);
    } else {
        document.getElementById("results").innerHTML = '<p><strong>Retrieving Orders...</strong></p>';
        document.getElementById("modals").innerHTML = '';

        retrieveeBayOrders(1);
        initProgressBar("Retrieving Orders...");

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

                if (getRadioValue('rptType') == 'shippingList') {
                    retrieveShopifyShippings(1);
                } else if (getRadioValue('rptType') == 'trackingList') {
                    retrieveShopifyTrackings(1);
                } else if (getRadioValue('rptType') == 'customerList') {
                    sortTable("customerTable", true);
                    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);
                    }
                } else {
                    retrieveShopifyOrders(1);
                }
            }
        }

        checkpagesToProcess();

        if (getRadioValue('rptType') == 'shippingList') {
            x = document.getElementById("printButton");
            if (x.className.indexOf("w3-show") == -1) {
                x.className += " w3-show";
            }
        } else if (getRadioValue('rptType') == 'orderList') {
            x = document.getElementById("dlOrderListButton");
            if (x.className.indexOf("w3-show") == -1) {
                x.className += " w3-show";
            }
        } else if (getRadioValue('rptType') == 'customerList') {
            x = document.getElementById("dlCustomerListButton");
            if (x.className.indexOf("w3-show") == -1) {
                x.className += " w3-show";
            }
        }
    }
}

function retrieveeBayOrders(pageNumber) {
    var i;
    var xml;
    var authErrorFlag = false;

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

    var valueStartDate = moment(document.getElementById('startDate').value + " 00:00:00", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
    var valueEndDate = moment(document.getElementById('endDate').value + " 23:59:59", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();

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

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

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

    xw.writeElementString('CreateTimeFrom', valueStartDate);
    xw.writeElementString('CreateTimeTo', valueEndDate);

    xw.writeElementString('IncludeFinalValueFee', 'true');
    xw.writeElementString('OrderRole', 'Seller');
    xw.writeElementString('OrderStatus', 'All');

    xw.writeStartElement('Pagination');
    xw.writeElementString('EntriesPerPage', configXmlRequestEntriesPerPage);
    xw.writeElementString('PageNumber', pageNumber.toString());
    xw.writeEndElement(); /* Pagination */

    xw.writeElementString('DetailLevel', 'ReturnAll');

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

    xw.writeEndElement(); /* GetOrdersRequest */
    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', 'GetOrders');
    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);

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

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

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

        if (obj.Message) {
            x.innerHTML += "<p>" + obj.Message + "</p>";
        }

        if (returnCode == 'Success' || (returnCode == 'Warning' && obj.Errors.ErrorCode == '21917182')) {
            if (getRadioValue('rptType') == 'shippingList') {
                createShipmentTable(obj, pageNumber);
            } else if (getRadioValue('rptType') == 'trackingList') {
                createTrackingTable(obj, pageNumber);
            } else if (getRadioValue('rptType') == 'customerList') {
                createCustomerTable(obj, pageNumber);
            } else {
                createOrderTable(obj, pageNumber);
            }

            x.innerHTML += '<p><strong>' + returnCode + ' (Orders ' + pageNumber + ' / ' + obj.PaginationResult.TotalNumberOfPages + ')</strong></p>';

            if (getRadioValue('rptType') == 'orderList') {
                printSummary();
            }

            if (obj.HasMoreOrders == 'true') {
                ++pagesToProcess;
                ++maxPagesToProcess;
                updateProgressBar(maxPagesToProcess, pagesProcessed);
                retrieveeBayOrders(pageNumber + 1);
            }

            document.getElementById("logging").innerHTML = html.join('');
            --pagesToProcess;
            ++pagesProcessed;
            updateProgressBar(maxPagesToProcess, pagesProcessed);
        } else {
            x.className += " process-errors";
            str = "<p><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/>";
                if (errors[i].LongMessage.includes('Auth')) {
                    authErrorFlag = true;
                }
            }
            str += "</p>";

            x.innerHTML += str;

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

    xhr.send(xml);
}

function retrieveShopifyOrders(page) {
    var sDate = moment(document.getElementById("startDate").value + " 00:00:00").format("YYYY-MM-DDTHH:mm:ssZ");
    var eDate = moment(document.getElementById("endDate").value + " 23:59:59").format("YYYY-MM-DDTHH:mm:ssZ");

    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var json = JSON.parse(this.responseText);
            if (json.orders.length > 0) {
                retrieveShopifyOrder(json);
            } else {
                // xxxxx last steps in the chain
                printOrderTotals();
                document.getElementById("logging").innerHTML = html.join('');

                sortTable("orderTable", true);
                document.getElementById("results").innerHTML += '<p><strong>Retrieving Shipping Costs...</strong></p>';
                findShippingCosts();
            }
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(configShopifyUrl + configShopifyOrdersUrl + '?page=' + ((page - 1) * configShopifyOrderLimit) + '&limit=' + configShopifyOrderLimit + '&status=any&created_at_min=' + sDate + '&created_at_max=' + eDate));
    xhttp.send();
}

function retrieveShopifyOrder(json) {
    var i, j;
    var title;
    var quantity;
    var itemId;
    var trackingNumber;
    var trackingStatus;
    var shipmentState;
    var shipmentDate;

    for (i = 0; i < json.orders.length; i++) {
        html.push('<tr>');
        html.push(tableCell(json.orders[i].created_at.substr(0, 10)));
        html.push(tableCell(json.orders[i].id + ' (' + json.orders[i].name + ')'));
        
        title = '';
        quantity = '';
        itemId = '';
        for (j = 0; j < json.orders[i].line_items.length; j++) {
            itemsSold++;
            if (j > 0) {
                title += '<br/>';
                quantity += '<br/>';
                itemId += '<br/>';
            }
            title += json.orders[i].line_items[j].title;
            quantity += json.orders[i].line_items[j].quantity;
            itemId += json.orders[i].line_items[j].product_id === null ? '' : json.orders[i].line_items[j].product_id;
        }

        html.push(tableCell(title));
        html.push(tableCell(itemId));
        html.push(tableCell('Shopify'));
        html.push(tableCell(quantity));
        html.push(tableCell('$' + json.orders[i].total_price_usd));
        html.push(tableCell('$0.00'));
        html.push(tableCell(''));
        html.push(tableCell('$0.00'));
        html.push(tableCell('$0.00'));
        html.push(tableCellLabel('Fee' + json.orders[i].id));
        html.push(tableCell(json.orders[i].total_tax));

        if (json.orders[i].shipping_address !== undefined) {
            shipmentState = json.orders[i].shipping_address.province_code;
        } else {
            shipmentState = configTaxStateId;
        }
        html.push(tableCell(shipmentState));
        html.push(tableCellLabel('PaidDate' + json.orders[i].id));
        html.push(tableCell(json.orders[i].payment_gateway_names !== undefined ? json.orders[i].payment_gateway_names.join(', ') : ''));
        html.push(tableCellLabel('TransactionId' + json.orders[i].id));

        shipmentDate = '';
        trackingNumber = '';
        trackingStatus = '';
        for (j = 0; j < json.orders[i].fulfillments.length; j++) {
            if (j > 0) {
                trackingNumber += '<br/>';
                trackingStatus += '<br/>';
                shipmentDate += '<br/>';
            }

            if (json.orders[i].fulfillments[j].tracking_number !== null) {
                trackingNumber = json.orders[i].fulfillments[j].tracking_company + ' ' + json.orders[i].fulfillments[j].tracking_number;
                trackingStatus = json.orders[i].fulfillments[j].shipment_status;
                shipmentDate += json.orders[i].fulfillments[j].created_at.substr(0, 10);
            }
        }

        html.push(tableCell(shipmentDate));
        html.push(tableCell(trackingNumber));
        html.push(tableCell(trackingStatus));
        html.push('</tr>');

        grossSales += Number(json.orders[i].total_price_usd);
    }

    // xxxxx last steps in the chain
    printOrderTotals();
    document.getElementById("logging").innerHTML = html.join('');

    sortTable("orderTable", true);
    document.getElementById("results").innerHTML += '<p><strong>Retrieving Shipping Costs...</strong></p>';
    findShippingCosts();
}

function retrieveShopifyShippings(page) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            //window.alert(this.responseText);
            var json = JSON.parse(this.responseText);
            if (json.orders[0] !== undefined) {
                retrieveShopifyShipping(json);
            }

            // xxxxx last steps in the chain
            printShipmentTotals();
            document.getElementById("logging").innerHTML = html.join('');

            sortTable("shippingTable", true);
            findThumbNails();
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(configShopifyUrl + configShopifyOrdersUrl + '?page=' + ((page - 1) * configShopifyOrderLimit) + '&limit=' + configShopifyOrderLimit + '&fulfillment_status=unshipped'));
    xhttp.send();
}

function retrieveShopifyShipping(json) {
    var i;

    for (i = 0; i < json.orders.length; i++) {
        totalAmount += parseFloat(json.orders[i].total_price);

        for (j = 0; j < json.orders[i].line_items.length; j++) {
            html.push('<tr>');

            html.push(tableCellSKU(json.orders[i].line_items[j].sku, json.orders[i].line_items[j].title));
            html.push(tableCell(json.orders[i].line_items[j].quantity));
            if (json.orders[i].line_items[j].product_id !== null) {
                html.push(tableCellAndLabel(json.orders[i].line_items[j].product_id, 'PictureURL' + json.orders[i].line_items[j].product_id));
            } else {
                html.push(tableCell(''));
            }
            html.push(tableCell(json.orders[i].line_items[j].title));
            html.push(tableCell(json.orders[i].name));
            html.push(tableCellDate(json.orders[i].created_at.substr(0, 10)));
            html.push(tableCell('$' + parseFloat(json.orders[i].line_items[j].price).toFixed(2)));
            html.push(tableCellHidden('Shopify'));

            itemsSold += Number(json.orders[i].line_items[j].quantity);

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

function retrieveShopifyTrackings(page) {
    var sDate = moment(document.getElementById("startDate").value + " 00:00:00").format("YYYY-MM-DDTHH:mm:ssZ");
    var eDate = moment(document.getElementById("endDate").value + " 23:59:59").format("YYYY-MM-DDTHH:mm:ssZ");

    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            //window.alert(this.responseText);
            var json = JSON.parse(this.responseText);
            if (json.orders[0] !== undefined) {
                retrieveShopifyTracking(json);
            }

            // xxxxx last in the chain
            printTrackingTotals();
            document.getElementById("logging").innerHTML = html.join('');
            sortTable("trackingTable", true);
            document.getElementById("results").innerHTML += '<p><strong>Retrieving Shipping Costs...</strong></p>';
            findShippingCosts();
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(configShopifyUrl + configShopifyOrdersUrl + '?page=' + ((page - 1) * configShopifyOrderLimit) + '&limit=' + configShopifyOrderLimit + '&fulfillment_status=shipped&status=closed&created_at_min=' + sDate + '&created_at_max=' + eDate));
    xhttp.send();
}

function retrieveShopifyTracking(json) {
    var i, j;
    var title;

    for (i = 0; i < json.orders.length; i++) {
        if (json.orders[i].shipping_lines[0] === undefined) {
            continue;
        }

        html.push('<tr>');
        html.push(tableCell(json.orders[i].created_at.substr(0, 10)));

        title = '';
        for (j = 0; j < json.orders[i].line_items.length; j++) {
            if (j > 0) {
                title += '<br/>';
            }
            title += json.orders[i].line_items[j].title;
        }

        html.push(tableCell(title));
        html.push(tableCell('N/A'));
        html.push(tableCellAndLabel(json.orders[i].shipping_address.city + ', ' + json.orders[i].shipping_address.province_code + ' ' + json.orders[i].shipping_address.zip, 'DeliveryAddress' + json.orders[i].fulfillments[0].tracking_number));
        html.push(tableCell(json.orders[i].fulfillments[0].created_at.substr(0, 10))); // best guess
        html.push(tableCell(json.orders[i].fulfillments[0].created_at.substr(0, 10)));
        html.push(tableCellAndLabel(json.orders[i].fulfillments[0].tracking_company + ' ' + json.orders[i].fulfillments[0].tracking_number, json.orders[i].fulfillments[0].tracking_number));
        html.push(tableCell(getCarrierService(json.orders[i].fulfillments[0].tracking_company, json.orders[i].fulfillments[0].tracking_number, true)));
        html.push(tableCellLabel('DeliveryDate' + json.orders[i].fulfillments[0].tracking_number));
        html.push(tableCellLabel('DeliveryDays' + json.orders[i].fulfillments[0].tracking_number));
        html.push(tableCellLabel('DeliveryStatus' + json.orders[i].fulfillments[0].tracking_number));

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

function createOrderTable(obj, pageNumber) {
    var i;
    var title;
    var trackingNumber;
    var quantity;
    var finalValueFee;
    var finalValueFeeAmount;
    var itemId;
    var taxAmount;
    var payAmount;

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

        html.push('<div class="border table-responsive">');
        html.push('<h3>Order List from ' + document.getElementById("startDate").value + ' to ' + document.getElementById("endDate").value + '</h3>');
        html.push('<table id="orderTable" class="table table-hover table-striped table-bordered small">');
        html.push('<thead class="thead-dark">');
        html.push('<tr>');

        html.push(tableHeader('Order Date'));
        html.push(tableHeader('Order Id'));
        html.push(tableHeader('Ttitle'));
        html.push(tableHeader('Item Id'));
        html.push(tableHeader('Sales Channel'));
        html.push(tableHeader('Quantity Purchased'));
        html.push(tableHeader('Payment Amount'));
        html.push(tableHeader('Shipping Received'));
        html.push(tableHeader('Return Cost'));
        html.push(tableHeader('Shipping Cost'));
        html.push(tableHeader('eBay Final Value Fee'));
        html.push(tableHeader('Payment Processor Fee'));
        html.push(tableHeader('Sales Tax Amount'));
        html.push(tableHeader('Ship To State'));
        html.push(tableHeader('Paid Date'));
        html.push(tableHeader('Payment Methods'));

        html.push(tableHeader('Payment Transaction ID'));
        html.push(tableHeader('Shipped Date'));
        html.push(tableHeader('Shipping Tracking Number'));
        html.push(tableHeader('Delivery Status'));

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

    var orders = getJsonArray(obj.OrderArray);
    for (var entry = 0; entry < orders[0].Order.length; entry++) {
        var order = orders[0].Order[entry];

        html.push('<tr>');

        html.push(tableCellDate(order.CreatedTime));
        html.push(tableCell(order.OrderID));

        title = '';
        trackingNumber = '';
        quantity = '';
        finalValueFee = '';
        finalValueFeeAmount = 0.0;
        itemId = '';
        taxAmount = 0.0;

        var transactions = getJsonArray(orders[0].Order[entry].TransactionArray.Transaction);
        for (i = 0; i < transactions.length; i++) {
            itemsSold++;
            if (i > 0) {
                title += '<br/>';
                quantity += '<br/>';
                itemId += '<br/>';
            }
            title += transactions[i].Item.Title;
            quantity += transactions[i].QuantityPurchased;
            finalValueFeeAmount += parseFloat(transactions[i].FinalValueFee.text);
            eBayFees += parseFloat(transactions[i].FinalValueFee.text);
            itemId += transactions[i].Item.ItemID;
            if (order.eBayCollectAndRemitTax == "true") {
                taxAmount += parseFloat(transactions[i].eBayCollectAndRemitTaxes.TotalTaxAmount.text);
            }
        }
        html.push(tableCell(title));
        html.push(tableCell(itemId));
        finalValueFee = '$' + finalValueFeeAmount.toFixed(2);

        var trackingDetails = getJsonArray(transactions[0].ShippingDetails.ShipmentTrackingDetails);
        for (i = 0; i < trackingDetails.length; i++) {
            trackingNumber += (i > 0 ? '<br/>' : '') + trackingDetails[i].ShippingCarrierUsed + ' ' + trackingDetails[i].ShipmentTrackingNumber;
        }

        html.push(tableCell('eBay'));
        html.push(tableCell(quantity));
        html.push(tableCell('$' + parseFloat(order.AmountPaid.text).toFixed(2)));
        grossSales += parseFloat(order.AmountPaid.text);

        html.push(tableCell('$' + parseFloat(order.ShippingServiceSelected.ShippingServiceCost.text).toFixed(2)));
        shippingRcvd += parseFloat(order.ShippingServiceSelected.ShippingServiceCost.text);

        html.push(tableCell(''));
        html.push(tableCellLabel('ShippingCost' + order.OrderID));
        html.push(tableCell(finalValueFee));

        if (order.ExternalTransaction !== undefined && order.ExternalTransaction.FeeOrCreditAmount !== undefined) {
/* bugbug hardcoded 2.7%
            html.push(tableCell('$' + parseFloat(order.ExternalTransaction.FeeOrCreditAmount.text).toFixed(2)));
            PayPalFees += parseFloat(order.ExternalTransaction.FeeOrCreditAmount.text);
*/
            paymentProcessingFees = parseFloat(order.AmountPaid.text) * 0.027;
            html.push(tableCell('$' + parseFloat(paymentProcessingFees).toFixed(2)));
            PayPalFees += paymentProcessingFees;
        } else {
            html.push(tableCell(''));
        }

        if (order.eBayCollectAndRemitTax == "true") {
            html.push(tableCell('$' + taxAmount.toFixed(2) + '*'));
        } else {
            html.push(tableCell('$0.00'));
        }
        
        html.push(tableCell(order.ShippingAddress.StateOrProvince));

        if (order.PaidTime !== undefined) {
            html.push(tableCellDate(order.PaidTime));
        } else {
            html.push(tableCell(''));
        }
        html.push(tableCell(order.CheckoutStatus.PaymentMethod));

        if (order.ExternalTransaction !== undefined && order.ExternalTransaction.ExternalTransactionID !== undefined) {
            html.push(tableCell(order.ExternalTransaction.ExternalTransactionID));
        } else {
            html.push(tableCell(''));
        }

        if (order.ShippedTime === undefined) {
            html.push(tableCell(''));
        } else {
            html.push(tableCellDate(order.ShippedTime));
        }
        html.push(tableCell(trackingNumber));
        html.push(tableCellLabel('Delivery' + order.OrderID));

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

function printOrderTotals() {
    html.push('</tbody>');
    html.push('<tfoot>');
    html.push('<tr>');
    html.push(tableCell('<strong>Totals</strong>'));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell('<strong>' + itemsSold + '</strong>'));
    html.push(tableCell('<strong>$' + grossSales.toFixed(2) + '</strong>'));
    html.push(tableCell('<strong>$' + shippingRcvd.toFixed(2) + '</strong>'));
    html.push(tableCell(''));
    html.push(tableCellLabel('ShippingTotal'));
    html.push(tableCell('<strong>$' + eBayFees.toFixed(2) + '</strong>'));
    html.push(tableCell('<strong>$' + PayPalFees.toFixed(2) + '</strong>'));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push('</tr>');
    html.push('</tfoot>');
    html.push('</table>');
    html.push('</div>');
}

function createCustomerTable(obj, pageNumber) {
    var i;
    var firstName;
    var lastName;
    var emailAddress;

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

        html.push('<div class="border table-responsive">');
        html.push('<h3>Customer List from ' + document.getElementById("startDate").value + ' to ' + document.getElementById("endDate").value + '</h3>');
        html.push('<table id="customerTable" class="table table-hover table-striped table-bordered small">');
        html.push('<thead class="thead-dark">');
        html.push('<tr>');

        html.push(tableHeader('First Name'));
        html.push(tableHeader('Last Name'));
        html.push(tableHeader('Email'));
        html.push(tableHeader('Company'));
        html.push(tableHeader('Address1'));
        html.push(tableHeader('Address2'));
        html.push(tableHeader('City'));
        html.push(tableHeader('Province'));
        html.push(tableHeader('Province Code'));
        html.push(tableHeader('Country'));
        html.push(tableHeader('Country Code'));
        html.push(tableHeader('Zip'));
        html.push(tableHeader('Phone'));
        html.push(tableHeader('Accepts Marketing'));
        html.push(tableHeader('Total Spent'));
        html.push(tableHeader('Total Orders'));
        html.push(tableHeader('Tags'));
        html.push(tableHeader('Note'));
        html.push(tableHeader('Tax Exempt'));

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

    var orders = getJsonArray(obj.OrderArray.Order);
    for (var entry = 0; entry < orders.length; entry++) {
        var order = obj.OrderArray.Order[entry];

        html.push('<tr>');

        firstName = '';
        lastName = '';
        emailAddress = '';

        var transactions = getJsonArray(order.TransactionArray.Transaction);
        for (i = 0; i < transactions.length; i++) {
            firstName = transactions[i].Buyer.UserFirstName;
            lastName = transactions[i].Buyer.UserLastName;
            emailAddress = transactions[i].Buyer.Email;
        }

        html.push(tableCell(firstName.toProperCase()));
        html.push(tableCell(lastName.toProperCase()));
        html.push(tableCell(emailAddress != 'Invalid Request' && emailAddress !== undefined ? emailAddress : ""));
        html.push(tableCell(''));
        html.push(tableCell(order.ShippingAddress.Street1.toProperCase()));
        html.push(tableCell(order.ShippingAddress.Street2.toProperCase()));
        html.push(tableCell(orders[entry].ShippingAddress.CityName.toProperCase()));
        html.push(tableCell(''));
        html.push(tableCell(order.ShippingAddress.StateOrProvince));
        html.push(tableCell(order.ShippingAddress.CountryName.toProperCase()));
        html.push(tableCell(order.ShippingAddress.Country));
        html.push(tableCell(order.ShippingAddress.PostalCode));
        html.push(tableCell(order.ShippingAddress.Phone));
        html.push(tableCell('no'));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell('ebay'));
        html.push(tableCell(order.BuyerUserID));
        html.push(tableCell('no'));

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


    if (obj.HasMoreOrders != 'true') {
        html.push('</tbody>');
        html.push('<tfoot>');
        html.push('<tr>');
        html.push(tableCell(''));
        html.push('</tr>');
        html.push('</tfoot>');
        html.push('</table>');
        html.push('</div>');
    }
}

function createShipmentTable(obj, pageNumber) {
    var i, j;

    if (pageNumber == 1) {
        totalAmount = 0.00;
        itemsSold = 0;

        document.getElementById("logging").innerHTML = '';
        html = [];

        html.push('<div class="border table-responsive">');
        html.push('<h3>Awaiting Shipments List from ' + document.getElementById("startDate").value + ' to ' + document.getElementById("endDate").value + '</h3>');
        html.push('<table id="shippingTable" class="table table-hover table-striped table-bordered small">');
        html.push('<thead class="thead-dark">');
        html.push('<tr>');

        html.push(tableHeader('SKU'));
        html.push(tableHeader('Quantity'));
        html.push(tableHeader('Thumbnail'));
        html.push(tableHeader('Ttitle'));
        html.push(tableHeader('Item Id'));
        html.push(tableHeader('Date'));
        html.push(tableHeader('Amount'));
        html.push(tableHeaderHidden('Sales Channel'));

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

    var orders = getJsonArray(obj.OrderArray.Order);
    for (var entry = 0; entry < orders.length; entry++) {
        if (orders[entry].OrderStatus == 'Completed' && orders[entry].ShippedTime === undefined && orders[entry].PaidTime !== undefined) {
            var transactions = getJsonArray(orders[entry].TransactionArray.Transaction);
            for (i = 0; i < transactions.length; i++) {
                itemsSold++;

                var title = getJsonValue(transactions[i].Item.Title);
                var buyerMessage = getJsonValue(orders[entry].BuyerCheckoutMessage);
                if (buyerMessage.length > 0) {
                    var s = buyerMessage.split("|||", 80);
                    title += '<br/><br/>Buyer Message: ';
                    for (j = 0; j < s.length; j++) {
                        title += s[j] + '<br/>';
                    }
                }

                html.push('<tr>');

                html.push(tableCellSKU(transactions[i].Item.SKU, transactions[i].Item.Title));
                html.push(tableCell(transactions[i].QuantityPurchased));
                html.push(tableCellLabel('PictureURL' + transactions[i].Item.ItemID));
                html.push(tableCell(title));
                html.push(tableCell(transactions[i].Item.ItemID));
                html.push(tableCellDate(orders[entry].CreatedTime));
                html.push(tableCell('$' + parseFloat(orders[entry].AmountPaid.text).toFixed(2) + (transactions.length > 1 ?'*' : '')));
                if (i === 0) {
                    totalAmount += parseFloat(orders[entry].AmountPaid.text);
                }
                html.push(tableCellHidden('eBay'));

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

function printShipmentTotals() {
    html.push('</tbody>');
    html.push('<tfoot>');
    html.push('<tr>');
    html.push(tableCell('<strong>Totals</strong>'));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell(''));
    html.push(tableCell('<strong>' + itemsSold + '</strong>'));
    html.push(tableCell('<strong>$' + totalAmount.toFixed(2) + '</strong>'));
    html.push(tableCellHidden(''));
    html.push('</tr>');
    html.push('</tfoot>');
    html.push('</table>');
    html.push('</div');
}

function createTrackingTable(obj, pageNumber) {
    var i;
    var title;
    var trackingNumber;
    var service;
    var quantity;
    var html_temp;
    var finalValueFee;
    var finalValueFeeAmount;
    var itemId;

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

        html.push('<div class="border table-responsive">');
        html.push('<h3>Shipment Tracking List from ' + document.getElementById("startDate").value + ' to ' + document.getElementById("endDate").value + '</h3>');
        html.push('<table id="trackingTable" class="table table-hover table-striped table-bordered small">');
        html.push('<thead class="thead-dark">');
        html.push('<tr>');

        html.push(tableHeader('Order Date'));
        html.push(tableHeader('Ttitle'));
        html.push(tableHeaderHidden('Order Id'));
        html.push(tableHeader('Shipping Cost'));
        html.push(tableHeader('Shipping Address'));
        html.push(tableHeader('Paid Date'));
        html.push(tableHeader('Shipped Date'));
        html.push(tableHeader('Shipping Tracking Number'));
        html.push(tableHeader('Service'));
        html.push(tableHeader('Delivery Date'));
        html.push(tableHeader('Duration (Days)'));
        html.push(tableHeader('Delivery Status'));

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

    var orders = getJsonArray(obj.OrderArray.Order);
    for (var entry = 0; entry < orders.length; entry++) {
        html_temp = [];
        var order = orders[entry];

        html_temp.push('<tr>');

        html_temp.push(tableCellDate(order.CreatedTime));

        title = '';
        trackingNumber = '';
        service = '';
        quantity = '';
        finalValueFee = '';
        finalValueFeeAmount = 0.0;
        itemId = '';

        var transactions = getJsonArray(order.TransactionArray.Transaction);
        for (title = '', i = 0; i < transactions.length; i++) {
            if (i > 0) {
                title += '<br/>';
                quantity += '<br/>';
                itemId += '<br/>';
            }
            title += transactions[i].Item.Title;
        }
        html_temp.push(tableCell(title));

        var trackingDetails = getJsonArray(transactions[0].ShippingDetails.ShipmentTrackingDetails);
        // only last 1
        for (i = 0; i < trackingDetails.length; i++) {
            trackingNumber = trackingDetails[i].ShippingCarrierUsed + ' ' + trackingDetails[i].ShipmentTrackingNumber;
            service = getCarrierService(trackingDetails[i].ShippingCarrierUsed, trackingDetails[i].ShipmentTrackingNumber, true);
        }

        html_temp.push(tableCellHidden(order.OrderID));
        html_temp.push(tableCellLabel('ShippingCost' + order.OrderID));
        html_temp.push(tableCellAndLabel(order.ShippingAddress.CityName + ', ' + order.ShippingAddress.StateOrProvince + ' ' + order.ShippingAddress.PostalCode, 'DeliveryAddress' + trackingNumber.substr(trackingNumber.indexOf(' ') + 1)));

        if (order.PaidTime !== undefined) {
            html_temp.push(tableCellDate(order.PaidTime));
        } else {
            html_temp.push(tableCell(''));
        }

        if (order.ShippedTime === undefined) {
            html_temp.push(tableCellLabel('ShippedDate' + trackingNumber.substr(trackingNumber.indexOf(' ') + 1)));
        } else {
            html_temp.push(tableCellDate(order.ShippedTime));
        }

        html_temp.push(tableCellAndLabel(trackingNumber, trackingNumber.substr(trackingNumber.indexOf(' ') + 1)));
        html_temp.push(tableCell(service));
        html_temp.push(tableCellLabel('DeliveryDate' + trackingNumber.substr(trackingNumber.indexOf(' ') + 1)));
        html_temp.push(tableCellLabel('DeliveryDays' + trackingNumber.substr(trackingNumber.indexOf(' ') + 1)));
        html_temp.push(tableCellLabel('DeliveryStatus' + trackingNumber.substr(trackingNumber.indexOf(' ') + 1)));

        html_temp.push('</tr>');

        if (trackingListDedupe.indexOf(trackingNumber.substr(trackingNumber.indexOf(' ') + 1)) == -1) {
            html.push(html_temp.join(''));
            trackingListDedupe.push(trackingNumber.substr(trackingNumber.indexOf(' ') + 1));
        }
    }
}

function printTrackingTotals() {
    html.push('</tbody>');
    html.push('<tfoot class="w3-hide">');
    html.push('<tr>');
    html.push(tableCell(''));
    html.push('</tr>');
    html.push('</tfoot>');
    html.push('</table>');
    html.push('</div>');
}

function getCarrierService(carrier, trackingNumber, flag) {
    if (flag && trackingList.indexOf(trackingNumber) == -1) {
        trackingList.push(trackingNumber);
    }

    if (carrier == "USPS") {
        if (trackingNumber.startsWith("9449")) {
            return ("Media Mail");
        } else if (trackingNumber.startsWith("9450")) {
            return ("Media Mail, Insured");
        } else if (trackingNumber.startsWith("94001")) {
            return ("First Class");
        } else if (trackingNumber.startsWith("9416")) {
            return ("First Class, Insured");
        } else if (trackingNumber.startsWith("92055")) {
            return ("Priority Mail");
        } else if (trackingNumber.startsWith("94073")) {
            return ("Certified Mail");
        } else if (trackingNumber.startsWith("93033")) {
            return ("Collect on Delivery");
        } else if (trackingNumber.startsWith("9405")) {
            return ("Regional Box A");
        } else if (trackingNumber.startsWith("82")) {
            return ("Global Express");
        } else if (trackingNumber.startsWith("EC")) {
            return ("Priority Mail Express International");
        } else if (trackingNumber.startsWith("92701") || trackingNumber.startsWith("9481") || trackingNumber.startsWith("EA")) {
            return ("Priority Mail Express");
        } else if (trackingNumber.startsWith("CP")) {
            return ("Priority Mail International");
        } else if (trackingNumber.startsWith("92088")) {
            return ("Registered Mail");
        } else if (trackingNumber.startsWith("9461") || trackingNumber.startsWith("9462")) {
            return ("Parcel Select Ground");
        } else if (trackingNumber.startsWith("92021")) {
            return ("Signature Confirmation");
        }
    } else if (carrier == "UPS") {
        if (trackingNumber.startsWith("1Z")) {
            var service = trackingNumber.substr(8, 2);

            if (service == '01') {
                return ('Next Day Air ("Red")');
            } else if (service == '02') {
                return ('UPS United States Second Day Air ("Blue")');
            } else if (service == '03') {
                return ('Ground');
            } else if (service == '12') {
                return ('Third Day Select');
            } else if (service == '13') {
                return ('Next Day Air Saver ("Red Saver")');
            } else if (service == '15') {
                return ('Next Day Air Early A.M.');
            } else if (service == '22') {
                return ('Ground - Returns Plus - Three Pickup Attempts');
            } else if (service == '32') {
                return ('Next Day Air Early A.M. - COD');
            } else if (service == '33') {
                return ('Next Day Air Early A.M. - Saturday Delivery, COD');
            } else if (service == '41') {
                return ('Next Day Air Early A.M. - Saturday Delivery');
            } else if (service == '42') {
                return ('Ground - Signature Required');
            } else if (service == '44') {
                return ('Next Day Air - Saturday Delivery');
            } else if (service == '66') {
                return ('Worldwide Express');
            } else if (service == '72') {
                return ('Ground - Collect on Delivery');
            } else if (service == '78') {
                return ('Ground - Returns Plus - One Pickup Attempt');
            } else if (service == '90') {
                return ('Ground - Returns - UPS Prints and Mails Label');
            } else if (service == 'A0') {
                return ('Next Day Air Early A.M. - Adult Signature Required');
            } else if (service == 'A1') {
                return ('Next Day Air Early A.M. - Saturday Delivery, Adult Signature Required');
            } else if (service == 'A2') {
                return ('Next Day Air - Adult Signature Required');
            } else if (service == 'A8') {
                return ('Ground - Adult Signature Required');
            } else if (service == 'A9') {
                return ('Next Day Air Early A.M. - Adult Signature Required, COD');
            } else if (service == 'AA') {
                return ('Next Day Air Early A.M. - Saturday Delivery, Adult Signature Required, COD');
            }
        }
    }

    return ("");
}

function retrieveFees(pageNumber) {
    var i;
    var xml;
    var authErrorFlag = false;

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

    var valueStartDate = document.getElementById('startDate').value + "T00:00:00.000Z";
    var valueEndDate = document.getElementById('endDate').value + "T23:59:59.999Z";

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

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

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

    xw.writeElementString('AccountEntrySortType', 'AccountEntryCreatedTimeAscending');
    xw.writeElementString('AccountHistorySelection', 'BetweenSpecifiedDates');
    xw.writeElementString('BeginDate', valueStartDate);
    xw.writeElementString('EndDate', valueEndDate);
    xw.writeElementString('ExcludeBalance', 'true');
    xw.writeElementString('ExcludeSummary', 'true');
    xw.writeElementString('IncludeNettedEntries', 'true');

    xw.writeStartElement('Pagination');
    xw.writeElementString('EntriesPerPage', configXmlRequestEntriesPerPage);
    xw.writeElementString('PageNumber', pageNumber.toString());
    xw.writeEndElement(); /* Pagination */

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

    xw.writeEndElement(); /* GetAccountRequest */
    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', 'GetAccount');
    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);

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

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

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

        if (obj.Message) {
            x.innerHTML += "<p>" + obj.Message + "</p>";
        }

        if (returnCode == 'Success' || (returnCode == 'Warning' && obj.Errors.ErrorCode == '21917182')) {
            createFeeTable(obj, pageNumber);

            x.innerHTML += '<p><strong>' + returnCode + ' (Fees/Credits ' + pageNumber + ' / ' + obj.PaginationResult.TotalNumberOfPages + ')</strong></p>';

            if (obj.HasMoreEntries == 'true') {
                ++pagesToProcess;
                ++maxPagesToProcess;
                updateProgressBar(maxPagesToProcess, pagesProcessed);
                retrieveFees(pageNumber + 1);
            }

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

            --pagesToProcess;
            ++pagesProcessed;
            updateProgressBar(maxPagesToProcess, pagesProcessed);
        } else {
            x.className += " process-errors";
            str = "<p><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/>";
                if (errors[i].LongMessage.includes('Auth')) {
                    authErrorFlag = true;
                }
            }
            str += "</p>";

            x.innerHTML += str;

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

            --pagesToProcess;
            ++pagesProcessed;
            updateProgressBar(maxPagesToProcess, pagesProcessed);
        }
    };

    xhr.send(xml);

    function checkpagesToProcess() {
        if (pagesToProcess > 0) {
            window.setTimeout(checkpagesToProcess, 100); // wait 100 milliseconds
        } else {
            sortTable("feeTable", true);
            x = document.getElementById("results");
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';

            endProgressBar();

            var y = document.getElementById("dlFeeListButton");
            if (y.className.indexOf("w3-show") == -1) {
                y.className += " w3-show";
            }

            if (!x.className.includes("process-errors")) {
                setTimeout(function() {
                    x.className = x.className.replace(" w3-show", "");
                }, 3000);
            }
        }
    }

    if (pageNumber == 1) {
        checkpagesToProcess();
    }
}

function createFeeTable(obj, pageNumber) {
    var i;

    if (pageNumber == 1) {
        totalAmount = 0;

        document.getElementById("logging").innerHTML = '';
        html = [];
        html.push('<div class="border table-responsive">');
        html.push('<h3>Fees and Credits List from ' + document.getElementById("startDate").value + ' to ' + document.getElementById("endDate").value + '</h3>');
        html.push('<table id="feeTable" class="table table-hover table-striped table-bordered small">');
        html.push('<thead class="thead-dark">');
        html.push('<tr>');

        html.push(tableHeader('Date'));
        html.push(tableHeader('Reference Id'));
        html.push(tableHeader('Title'));
        html.push(tableHeader('Item Id'));
        html.push(tableHeader('Fee Type'));
        html.push(tableHeader(''));
        html.push(tableHeader(''));
        html.push(tableHeader(''));
        html.push(tableHeader(''));
        html.push(tableHeader(''));
        html.push(tableHeader('Amount'));

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

    for (i = 0; i < obj.AccountEntries.AccountEntry.length; i++) {
        var AccountEntry = obj.AccountEntries.AccountEntry[i];
/*        if ((!AccountEntry.Description.includes('Payment') && !AccountEntry.Description.includes('Final Value Fee') && AccountEntry.GrossDetailAmount.text != '0.0' && AccountEntry.NetDetailAmount.text != '0.0') ||
            (AccountEntry.Description.includes('Final Value Fee') && AccountEntry.NetDetailAmount.text.substr(0, 1) == '-')) {
*/
            if (!(AccountEntry.Description == 'Payment' && AccountEntry.RefNumber == 0)) {
            html.push('<tr>');

            html.push(tableCellDate(AccountEntry.Date));
            html.push(tableCell(AccountEntry.RefNumber));
            html.push(tableCell(AccountEntry.Title));
            html.push(tableCell(AccountEntry.ItemID));
            html.push(tableCell(AccountEntry.Description));
            html.push(tableHeader(''));
            html.push(tableHeader(''));
            html.push(tableHeader(''));
            html.push(tableHeader(''));
            html.push(tableHeader(''));
            html.push(tableCell('$' + parseFloat(AccountEntry.GrossDetailAmount.text).toFixed(2)));
            totalAmount += parseFloat(AccountEntry.GrossDetailAmount.text);

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

    if (obj.HasMoreEntries != 'true') {
        html.push('</tbody>');
        html.push('<tfoot>');
        html.push('<tr>');
        html.push(tableCell('<strong>Totals</strong>'));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell(''));
        html.push(tableCell('<strong>$' + totalAmount.toFixed(2) + '</strong>'));
        html.push('</tr>');
        html.push('</tfoot>');
        html.push('</table>');
        html.push('</div>');
    }
}


function tableCellDate(utcDate) {
    var localDate = new Date(utcDate);
    return ('<td>' + localDate.yyyymmdd() + '</td>');
}

function tableCellSKU(str, title) {
    if (str === undefined) {
        str = '';
    }

    if (str.indexOf(" - ") > 0) {
        str = str.substr(0, str.indexOf(" - "));
    }

    if (str.startsWith("Batch") && !isNaN(str.substr(6))) {
        var batchNo = Number(str.substr(6));
        str = "Batch " + pad(batchNo, 2);
    }

    if (title.includes('(DVD') || title.includes('(HD') || title.includes('(Blu')) {
        str = 'DVD ' + str;
    } else if (title.includes('(CD')) {
        str = 'CD ' + str;
    } else if (title.includes('Hardcover') || title.includes('Paperback')) {
        str = 'Book ' + str;
    }

    return ('<td>' + str + '</td>');
}

function retrieveCancelReturn(pageNumber) {
    if (eBayAuthTokenFlag === false) {
        return;
    }

    var valueStartDate = document.getElementById('startDate').value + "T00:00:00.000Z";
    var valueEndDate = document.getElementById('endDate').value + "T23:59:59.999Z";

    url = configeBayPostOrder + "/return/search?";
    url += "creation_date_range_from=" + valueStartDate;
    url += "&creation_date_range_to=" + valueEndDate;
    url += "&return_state=CLOSED";

    var xhttp = new XMLHttpRequest();

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

            createCancelReturnTable(obj, pageNumber, true);

            if (obj.paginationOutput.totalPages > pageNumber) {
                ++pagesToProcess;
                ++maxPagesToProcess;
                updateProgressBar(maxPagesToProcess, pagesProcessed);
                retrieveCancelReturn(pageNumber + 1);
            }

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

            --pagesToProcess;
            ++pagesProcessed;
            updateProgressBar(maxPagesToProcess, pagesProcessed);
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
    xhttp.setRequestHeader("X-Authorization", "TOKEN " + eBayAuthToken);
    xhttp.setRequestHeader("Content-Type", "application/json");
    xhttp.setRequestHeader("X-EBAY-C-MARKETPLACE-ID", "EBAY-US");
    xhttp.send();

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

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

            retrieveCancel(1);
        }
    }

    if (pageNumber == 1) {
        checkpagesToProcess();
    }
}

function retrieveCancel(pageNumber) {
    if (eBayAuthTokenFlag === false) {
        return;
    }

    var valueStartDate = document.getElementById('startDate').value + "T00:00:00.000Z";
    var valueEndDate = document.getElementById('endDate').value + "T23:59:59.999Z";

    url = configeBayPostOrder + "/cancellation/search?";
    url += "creation_date_range_from=" + valueStartDate;
    url += "&creation_date_range_to=" + valueEndDate;
    url += "&return_state=CLOSED";

    var xhttp = new XMLHttpRequest();

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

            createCancelReturnTable(obj, pageNumber, false);

            if (obj.paginationOutput.totalPages > pageNumber) {
                ++pagesToProcess;
                ++maxPagesToProcess;
                updateProgressBar(maxPagesToProcess, pagesProcessed);
                retrieveCancel(pageNumber + 1);
            }

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

            --pagesToProcess;
            ++pagesProcessed;
            updateProgressBar(maxPagesToProcess, pagesProcessed);
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
    xhttp.setRequestHeader("X-Authorization", "TOKEN " + eBayAuthToken);
    xhttp.setRequestHeader("Content-Type", "application/json");
    xhttp.setRequestHeader("X-EBAY-C-MARKETPLACE-ID", "EBAY-US");
    xhttp.send();

    function checkpagesToProcess() {
        if (pagesToProcess > 0) {
            window.setTimeout(checkpagesToProcess, 100); // wait 100 milliseconds
        } else {
            sortTable("cancelReturnTable", true);
            x = document.getElementById("results");
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';

            endProgressBar();

            var y = document.getElementById("dlCancelReturnListButton");
            if (y.className.indexOf("w3-show") == -1) {
                y.className += " w3-show";
            }

            if (!x.className.includes("process-errors")) {
                setTimeout(function() {
                    x.className = x.className.replace(" w3-show", "");
                }, 3000);
            }
        }
    }

    if (pageNumber == 1) {
        checkpagesToProcess();
    }
}
function createCancelReturnTable(obj, pageNumber, flag) {
    var i;

    if (pageNumber == 1 && flag) {
        totalAmount = 0;

        document.getElementById("logging").innerHTML = '';
        html = [];

        html.push('<div class="border table-responsive">');
        html.push('<h3>Cancellations and Returns List from ' + document.getElementById("startDate").value + ' to ' + document.getElementById("endDate").value + '</h3>');
        html.push('<table id="cancelReturnTable" class="table table-hover table-striped table-bordered small">');
        html.push('<thead class="thead-dark">');
        html.push('<tr>');

        html.push(tableHeader('Date'));
        html.push(tableHeader('Order Id'));
        html.push(tableHeader('Title'));
        html.push(tableHeader('Item ID'));
        html.push(tableHeader('Reason'));
        html.push(tableHeader('Status'));
        html.push(tableHeader(''));
        html.push(tableHeader(''));
        html.push(tableHeader('Amount'));

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

    if (flag) {
        for (i = 0; obj.members !== undefined && i < obj.members.length; i++) {
            var returnEntry = obj.members[i];
            html.push('<tr>');

            html.push(tableCellDate(returnEntry.creationInfo.creationDate.value.substr(0,10)));
            html.push(tableCell(returnEntry.orderId));
            html.push(tableCell(returnEntry.creationInfo.item.itemTitle));
            html.push(tableCell(returnEntry.creationInfo.item.itemId));
            html.push(tableCell(returnEntry.creationInfo.reason));
            html.push(tableCell(returnEntry.status));
            html.push(tableCell(''));
            html.push(tableCell(''));
            if (returnEntry.sellerTotalRefund.actualRefundAmount !== undefined) {
                html.push(tableCell('$' + parseFloat(returnEntry.sellerTotalRefund.actualRefundAmount.value).toFixed(2)));
                totalAmount += parseFloat(returnEntry.sellerTotalRefund.actualRefundAmount.value);
            } else{
                html.push(tableCell('$' + parseFloat(returnEntry.sellerTotalRefund.estimatedRefundAmount.value).toFixed(2)));
                totalAmount += parseFloat(returnEntry.sellerTotalRefund.estimatedRefundAmount.value);
            }

            html.push('</tr>');
        }
    } else{
        for (i = 0; obj.cancellations !== undefined && i < obj.cancellations.length; i++) {
            var cancelEntry = obj.cancellations[i];

            if (cancelEntry.cancelStatus == 'CANCEL_CLOSED_WITH_REFUND') {
                html.push('<tr>');

                html.push(tableCellDate(cancelEntry.cancelCloseDate.value.substr(0,10)));
                html.push(tableCell(cancelEntry.legacyOrderId));
                html.push(tableCell(cancelEntry.lineItems[0].itemTitle));
                html.push(tableCell(cancelEntry.lineItems[0].itemId));
                html.push(tableCell(cancelEntry.requestorType + ' / ' + cancelEntry.cancelCloseReason));
                html.push(tableCell(cancelEntry.cancelStatus));
                html.push(tableCell(''));
                html.push(tableCell(''));
                html.push(tableCell('$' + parseFloat(cancelEntry.requestRefundAmount.value).toFixed(2)));
                totalAmount += parseFloat(cancelEntry.requestRefundAmount.value);

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

    if (!flag) {
        if (obj.HasMoreEntries != 'true') {
            html.push('</tbody>');
            html.push('<tfoot>');
            html.push('<tr>');
            html.push(tableCell('<strong>Totals</strong>'));
            html.push(tableCell(''));
            html.push(tableCell(''));
            html.push(tableCell(''));
            html.push(tableCell(''));
            html.push(tableCell(''));
            html.push(tableCell(''));
            html.push(tableCell(''));
            html.push(tableCell('<strong>$' + totalAmount.toFixed(2) + '</strong>'));
            html.push('</tr>');
            html.push('</tfoot>');
            html.push('</table>');
            html.push('</div>');
        }
    }
}

function sortTable(tableName, stringSortFlag = false){
    var tbl = document.getElementById(tableName).tBodies[0];
    var sortnr;
    var store = [];
    for (var i = 0, len = tbl.rows.length; i < len; i++) {
        var row = tbl.rows[i];
        if (stringSortFlag) {
            sortnr = row.cells[0].textContent || row.cells[0].innerText;
            store.push([sortnr, row]);
        } else {
            sortnr = parseInt(row.cells[0].textContent || row.cells[0].innerText);
            if(!isNaN(sortnr)) store.push([sortnr, row]);
        }
    }
    store.sort(function(x,y){
        if (stringSortFlag) {
            return x[0] > y[0];
        } else {
            return x[0] - y[0];
        }
    });
    for(var i=0, len=store.length; i<len; i++){
        tbl.appendChild(store[i][1]);
    }
    store = null;
}

function printData() {
    var printContent = document.getElementById("printTable");

    var num;
    var cssReference = [];
    var uniqueName = new Date();

    var windowName = 'Print' + uniqueName.getTime();
    var printWindow = window.open(num, windowName, 'left=50000,top=50000,width=0,height=0');
    cssReference[0] = printWindow.document.createElement("link");
    cssReference[0].href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css";
    cssReference[0].rel = "stylesheet";
    cssReference[0].type = "text/css";
    cssReference[1] = printWindow.document.createElement("link");
    cssReference[1].href = "css/style.css";
    cssReference[1].rel = "stylesheet";
    cssReference[1].type = "text/css";

    printWindow.document.write(printContent.outerHTML.replace("table-bordered", "").replace("table-striped", "").replace("table-hover", ""));
    printWindow.document.getElementsByTagName('head')[0].appendChild(cssReference[0]);
    printWindow.document.getElementsByTagName('head')[0].appendChild(cssReference[1]);

    printWindow.document.close();
    printWindow.focus();
    printWindow.print();
    printWindow.close();
}

function printSummary() {
    var profit = grossSales + shippingRcvd - shippingCost - eBayFees - PayPalFees;

    document.getElementById("summary").innerHTML = '<h2>Profit: ' + profit.toFixed(2) + '</h3>';
}

function findThumbNails() {
    var i;
    var x = document.getElementById("shippingTable");

    thumbnailsToProcess = 0;
    thumbnailsProcessed = 0;
    maxThumbnailsToProcess = 0;
    initProgressBar("");

    for (i = 1; i < (x.rows.length - 1); i++) {
        if (x.rows[i].cells[7].innerHTML == 'eBay' && x.rows[i].cells[2] !== undefined && x.rows[i].cells[2].innerHTML.length < 1) {
            ++thumbnailsToProcess;
            ++maxThumbnailsToProcess;
            updateProgressBar(maxThumbnailsToProcess, thumbnailsProcessed);
            getThumbNail(x.rows[i].cells[4].innerHTML);
        } else if (x.rows[i].cells[7].innerHTML == 'Shopify' && x.rows[i].cells[2] !== undefined && x.rows[i].cells[2].innerHTML.length > 0) {
            ++thumbnailsToProcess;
            ++maxThumbnailsToProcess;
            updateProgressBar(maxThumbnailsToProcess, thumbnailsProcessed);
            getShopifyThumbNail(x.rows[i].cells[2].innerHTML);
        }
    }

    function checkthumbnailsToProcess() {
        if (thumbnailsToProcess > 0) {
            window.setTimeout(checkthumbnailsToProcess, 100); // wait 100 milliseconds
        } else {
            endProgressBar();
            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);
            }
        }
    }

    checkthumbnailsToProcess();
}

function getThumbNail(itemId) {
    // Construct the getSingleItem request
    url = configeBayShopping + "?";
    url += "callname=GetSingleItem";
    url += "&responseencoding=JSON";
    url += "&appid=" + configAppid;
    url += "&version=" + configeBayShoppingVersion;
    url += "&ItemID=";
    url += itemId;

    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            if (this.responseText) {
                _cb_getThumbNail(JSON.parse(this.responseText));
            } else {
                getThumbNail(itemId);
            }
        }
    };

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

function _cb_getThumbNail(root) {
    var ack = root.Ack;

    if (ack == 'Failure' || ack == 'PartialFailure') {
        return;
    }

    var JsonObj = typeof root.Item != 'object' ? JSON.parse(root.Item) : root.Item;
    var ItemID = JsonObj.ItemID;
    var PictureURL = getJsonArray(JsonObj.PictureURL);

    document.getElementById('PictureURL' + ItemID).innerHTML = '<img src="' + PictureURL[0] + '" style="max-height:100px">';
    --thumbnailsToProcess;
    ++thumbnailsProcessed;
    updateProgressBar(maxThumbnailsToProcess, thumbnailsProcessed);
}

function getShopifyThumbNail(productId) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            //window.alert(this.responseText);
            var json = JSON.parse(this.responseText);
            if (json.product !== undefined) {
                document.getElementById('PictureURL' + productId).innerHTML = '<img src="' + json.product.image.src + '" style="max-height:100px">';
            }
            --thumbnailsToProcess;
            ++thumbnailsProcessed;
            updateProgressBar(maxThumbnailsToProcess, thumbnailsProcessed);
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(configShopifyUrl + 'products/' + productId + '.json?fields=image'));
    xhttp.send();
}

function findShippingCosts() {
    var i;
    var x;

    shippingsToProcess = 0;
    shippingsProcessed = 0;
    maxShippingsToProcess = 0;
    initProgressBar("Retrieving Shipping Costs...");

    if (getRadioValue('rptType') == 'trackingList') {
        x = document.getElementById("trackingTable");
    } else {
        x = document.getElementById("orderTable");
    }

    for (i = (x.rows.length - 1); i > 0; i--) {
        if (getRadioValue('rptType') == 'trackingList') {
            if (x.rows[i].cells[3] !== undefined && x.rows[i].cells[3].innerHTML.length < 1) {
                if (x.rows[i].cells[7] !== undefined && x.rows[i].cells[7].innerHTML.length < 1) {
                    document.getElementById("trackingTable").deleteRow(i);
                } else {
                    ++shippingsToProcess;
                    ++maxShippingsToProcess;
                    updateProgressBar(maxShippingsToProcess, shippingsProcessed);
                    getShippingCost(x.rows[i].cells[2].innerHTML);
                }
            }
        } else {
            if (x.rows[i].cells[4].innerHTML == 'eBay' && x.rows[i].cells[9] !== undefined && x.rows[i].cells[9].innerHTML.length < 1) {
                ++shippingsToProcess;
                ++maxShippingsToProcess;
                updateProgressBar(maxShippingsToProcess, shippingsProcessed);
                getShippingCost(x.rows[i].cells[1].innerHTML);
            } else if (x.rows[i].cells[4].innerHTML == 'Shopify') {
                ++shippingsToProcess;
                ++maxShippingsToProcess;
                updateProgressBar(maxShippingsToProcess, shippingsProcessed);
                getPaymentTransaction(x.rows[i].cells[1].innerHTML);
            }
        }
    }

    function checkshippingsToProcess() {
        if (shippingsToProcess > 0) {
            window.setTimeout(checkshippingsToProcess, 100); // wait 100 milliseconds
        } else {
            endProgressBar();
            x = document.getElementById("results");
            if (getRadioValue('rptType') != 'trackingList') {
                document.getElementById("ShippingTotal").innerHTML = '<strong>$' + shippingCost.toFixed(2) + '</strong>';
                x.innerHTML += '<p><strong>Report Finished!</strong></p>';
                if (!x.className.includes("process-errors")) {
                    setTimeout(function() {
                        x.className = x.className.replace(" w3-show", "");
                    }, 3000);
                }
            } else {
                x.innerHTML += '<p><strong>Retrieving Carrier Tracking...</strong></p>';
                getTrackingDetails();
            }
        }
    }

    checkshippingsToProcess();
}

function getShippingCost(OrderId) {
    var i;
    var xml;
    var correlationId;
    var shippingCostStr;
    var deliveryStatus;
    var authErrorFlag = false;

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

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

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

    xw.writeElementString('OrderID', OrderId);
    xw.writeElementString('MessageID', OrderId);

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

    xw.writeEndElement(); /* GetSellingManagerSaleRecordRequest */
    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', 'GetSellingManagerSaleRecord');
    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);

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

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

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

        if (obj.Message) {
            x.innerHTML += "<p>" + obj.Message + "</p>";
        }

        if (returnCode == 'Success' || (returnCode == 'Warning' && obj.Errors.ErrorCode == '21917182')) {
            correlationId = obj.CorrelationID;
            deliveryStatus = '';
            shippingCostStr = '';

            if (obj.SellingManagerSoldOrder.ActualShippingCost !== undefined &&
                obj.SellingManagerSoldOrder.ActualShippingCost.text != '0.0' &&
                document.getElementById('ShippingCost' + correlationId).innerHTML.length < 1) {
                shippingCostStr = '$' + parseFloat(obj.SellingManagerSoldOrder.ActualShippingCost.text).toFixed(2);
                shippingCost += parseFloat(obj.SellingManagerSoldOrder.ActualShippingCost.text);
                document.getElementById('ShippingCost' + correlationId).innerHTML = shippingCostStr;
                if (getRadioValue('rptType') == 'orderList') {
                    printSummary();
                }
            }

            if (getRadioValue('rptType') != 'trackingList') {
                var soldTransactions = getJsonArray(obj.SellingManagerSoldOrder.SellingManagerSoldTransaction);
                for (i = 0; i < soldTransactions.length; i++) {
                    if (soldTransactions[i].Shipment !== undefined && soldTransactions[i].Shipment.DeliveryStatus !== undefined) {
                        deliveryStatus += (i > 0 ? '<br/>' : '') + soldTransactions[i].Shipment.DeliveryStatus;
                    }
                }
                document.getElementById('Delivery' + correlationId).innerHTML = deliveryStatus;
            }
        } else {
            x.className += " process-errors";
            str = "<p><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/>";
                if (errors[i].LongMessage.includes('Auth')) {
                    authErrorFlag = true;
                }
            }
            str += "</p>";

            x.innerHTML += str;

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

        --shippingsToProcess;
        ++shippingsProcessed;
        updateProgressBar(maxShippingsToProcess, shippingsProcessed);
    };

    xhr.send(xml);
}

function getPaymentTransaction(fullId) {
    var id = fullId.substr(0, fullId.indexOf(' '));
    var i;
    var transFee = 0.00;
    var transFeeStr = '';
    var transDate = '';
    var transId = '';

    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            //window.alert(this.responseText);
            var json = JSON.parse(this.responseText);
            var transactions = getJsonArray(json.transactions);
            for (i = 0; i < transactions.length; i++) {
                transDate = getJsonValue(transactions[i].created_at).substr(0, 10);
                document.getElementById('PaidDate' + id).innerHTML = transDate;

                var gateway = getJsonValue(transactions[i].gateway);
                if (gateway == 'shopify_payments') {
                    transId = getJsonValue(transactions[i].id);
                    transFee = Number(getJsonValue(transactions[i].receipt.fee_amount)) / 100;
                } else if (gateway == 'paypal') {
                    transId = getJsonValue(transactions[i].authorization);
                    transFee = Number(getJsonValue(transactions[i].receipt.fee_amount));
                } else if (gateway == 'manual') {
                    transId = getJsonValue(json.transactions[i].id);
                }

                document.getElementById('TransactionId' + id).innerHTML = transId;

                transFeeStr = '$' + parseFloat(transFee).toFixed(2);
                PayPalFees += transFee;
                document.getElementById('Fee' + id).innerHTML = transFeeStr;
            }

            --shippingsToProcess;
            ++shippingsProcessed;
            updateProgressBar(maxShippingsToProcess, shippingsProcessed);
        }
    };

    xhttp.open("GET", configProxyUrl, true);
    xhttp.setRequestHeader("X-Proxy-Url", encodeURI(configShopifyUrl + configShopifyTransactionsUrl1 + id + configShopifyTransactionsUrl2));
    xhttp.send();
}

function getTrackingDetails() {
    var i;
    var x;

    trackingNumbersToProcess = 0;
    trackingNumbersProcessed = 0;
    maxTrackingNumbersToProcess = 0;
    initProgressBar("Retrieving Carrier Tracking...");

    for (i = 0; i < trackingList.length; i++) {
        ++trackingNumbersToProcess;
        ++maxTrackingNumbersToProcess;
        if (trackingList[i].substr(0, 2) == '1Z') {
            getUPSTracking(trackingList[i]);
        } else {
            getUSPSTracking(trackingList[i]);
        }
    }

    function checkTrackingsToProcess() {
        if (trackingNumbersToProcess > 0) {
            window.setTimeout(checkTrackingsToProcess, 100); // wait 100 milliseconds
        } else {
            endProgressBar();
            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);
            }
        }
    }

    checkTrackingsToProcess();
}

function getUSPSTracking(searchNumber) {
    var j;
    var str;
    var url;
    var trackingNumber;
    var summary;
    var detail;
    var deliveryDate;
    var createDate;
    var duration;
    var lastUpdate;
    var lastEvent;
    var footer;

    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var obj = XMLparse(this.responseXML, false);

            if (obj.TrackResponse.TrackInfo.TrackSummary === undefined) {
                --trackingNumbersToProcess;
                ++trackingNumbersProcessed;
                updateProgressBar(maxTrackingNumbersToProcess, trackingNumbersProcessed);
                return;
            }

            var trackingInfo = obj.TrackResponse.TrackInfo;

            trackingNumber = trackingInfo.ID;
            summary = formatUSPSTrackingLine(trackingInfo.TrackSummary);
            detail = '';
            footer = '';
            deliveryDate = '';
            duration = '';
            lastUpdate = summary.substr(8, 10);
            lastEvent = trackingInfo.TrackSummary.Event;

            if (document.getElementById('DeliveryStatus' + trackingNumber) === null) {
                --trackingNumbersToProcess;
                ++trackingNumbersProcessed;
                updateProgressBar(maxTrackingNumbersToProcess, trackingNumbersProcessed);
                return;
            }

            if (trackingInfo.TrackDetail !== undefined && trackingInfo.TrackDetail.length > 0) {
                for (j = 0; j < trackingInfo.TrackDetail.length; j++) {
                    detail += formatUSPSTrackingLine(trackingInfo.TrackDetail[j]);
                }

                createDate = moment(trackingInfo.TrackDetail[(trackingInfo.TrackDetail.length - 1)].EventDate, "MMMM DD, YYYY").format('YYYY-MM-DD');
                footer = 'Enroute since ' + createDate + ' (' + moment().diff(createDate, 'days') + ' days)';

                if (summary.includes("Delivered")) {
                    deliveryDate = summary.substr(8, 10);
                    duration = moment(deliveryDate).diff(createDate, 'days');
                    document.getElementById('DeliveryStatus' + trackingNumber).style.color = "green";
                    footer = 'Delivered in ' + moment(deliveryDate).to(createDate, 'days');
                } else if (moment().diff(lastUpdate, 'days') > 3) {
                    document.getElementById('DeliveryStatus' + trackingNumber).style.color = "red";
                }
            }

            document.getElementById('DeliveryStatus' + trackingNumber).innerHTML = lastEvent;
            document.getElementById('DeliveryDays' + trackingNumber).innerHTML = duration;
            document.getElementById('DeliveryDate' + trackingNumber).innerHTML = deliveryDate;

            str = document.getElementById(trackingNumber).innerHTML;
            if (!str.startsWith('<button')) {
                document.getElementById(trackingNumber).innerHTML = '<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#mod' + trackingNumber + '">' + str + '</button>';

                str = '<div id="mod' + trackingNumber + '" class="modal">';
                str += '<div class="modal-dialog modal-lg">';
                str += '<div class="modal-content">';
                str += '<div class="modal-header">';
                str += '<h3>' + trackingNumber + ' (USPS ' + getCarrierService("USPS", trackingNumber, false) + ')</h3>';
                str += '<button type="button" class="close" data-dismiss="modal">&times;</button>';
                str += '</div>';
                str += '<div class="modal-body">';
                str += '<table class="table border small">';
                str += '<thead class="thead-dark">';
                str += '<tr>';
                str += '<th>DATE</th>';
                str += '<th>TIME</th>';
                str += '<th>STATUS</th>';
                str += '<th>LOCATION</th>';
                str += '</tr>';
                str += '</thead>';
                str += '<tbody>';
                str += summary;
                str += detail;
                str += '</tbody>';
                str += '</table>';
                str += '</div>';
                str += '<div class="modal-footer">';
                str += '<p>' + document.getElementById('DeliveryAddress' + trackingNumber).innerHTML + ' - ' + footer + '</p>';
                str += '</div>';
                str += '</div>';
                str += '</div>';
                str += '</div>';

                document.getElementById("modals").innerHTML += str;
            }

            --trackingNumbersToProcess;
            ++trackingNumbersProcessed;
            updateProgressBar(maxTrackingNumbersToProcess, trackingNumbersProcessed);
        }
    };

    url = configUSPSUrl + '?API=TrackV2&XML=';
    url += '<TrackFieldRequest USERID="';
    url += configUSPSUserId;
    url += '">';
    url += '<TrackID ID="' + searchNumber + '"></TrackID>';
    url += '</TrackFieldRequest>';
    url = url.replace(/ /g, '%20');

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

function formatUSPSTrackingLine(t) {
    var str = '';

    if (t !== undefined) {
        str = '<tr>';

        str += '<td>' + moment(t.EventDate, "MMMM DD, YYYY").format('YYYY-MM-DD') + '</td>';

        str += '<td>';
        if (t.EventTime.length > 0) {
            str += ' ' + moment(t.EventTime, "hh:mm a").format('HH:mm');
        }
        str += '</td>';

        str += '<td>' + t.Event + '</td>';

        str += '<td>';
        if (t.EventCity.length > 0) {
            str += t.EventCity;
            if (t.EventState.length > 0) {
                str += ", " + t.EventState + ' ' + t.EventZIPCode;
            }
        }
        str += '</td>';

        str += '</tr>';
    }

    return (str);
}

function getUPSTracking(trackingNumber) {
    var xhr = new XMLHttpRequest();

    var xml = '<?xml version="1.0"?>';
    xml += '<AccessRequest xml:lang="en-US">';
    xml += '<AccessLicenseNumber>' + configUPSAccessKey + '</AccessLicenseNumber>';
    xml += '<UserId>' + configUPSUsername + '</UserId>';
    xml += '<Password>' + configUPSPassword + '</Password>';
    xml += '</AccessRequest>';
    xml += '<?xml version="1.0"?>';
    xml += '<TrackRequest xml:lang="en-US">';
    xml += '<Request>';
    xml += '<TransactionReference>';
    xml += '<CustomerContext>' + 'MUNA Trading' + '</CustomerContext>';
    xml += '</TransactionReference>';
    xml += '<RequestAction>Track</RequestAction>';
    xml += '<RequestOption>1</RequestOption>';
    xml += '</Request>';
    xml += '<TrackingNumber>' + trackingNumber + '</TrackingNumber>';
    xml += '</TrackRequest>';

    xhr.onload = () => {
        var jsonObj = XMLparse(xhr.responseXML, false);
        var obj = jsonObj.TrackResponse;

        if (obj.Response.ResponseStatusDescription != 'Success') {
            --trackingNumbersToProcess;
            ++trackingNumbersProcessed;
            updateProgressBar(maxTrackingNumbersToProcess, trackingNumbersProcessed);
            return;
        }

        trackingNumber = obj.Shipment.ShipmentIdentificationNumber;
        summary = formatUPSTrackingLine(obj.Shipment.Package.Activity[0]);
        detail = '';
        footer = '';
        deliveryDate = '';
        duration = '';
        lastUpdate = moment(obj.Shipment.Package.Activity[0].Status.Date, "YYYYMMDD").format('YYYY-MM-DD');
        lastEvent = obj.Shipment.Package.Activity[0].Status.StatusType.Description;

        if (document.getElementById('DeliveryStatus' + trackingNumber) === null) {
            --trackingNumbersToProcess;
            ++trackingNumbersProcessed;
            updateProgressBar(maxTrackingNumbersToProcess, trackingNumbersProcessed);
            return;
        }

        if (obj.Shipment.Package.Activity !== undefined && obj.Shipment.Package.Activity.length > 0) {
            for (j = 0; j < obj.Shipment.Package.Activity.length; j++) {
                detail += formatUPSTrackingLine(obj.Shipment.Package.Activity[j]);
            }

            createDate = moment(obj.Shipment.PickupDate, "YYYYMMDD").format('YYYY-MM-DD');
            footer = 'Enroute since ' + createDate + ' (' + moment().diff(createDate, 'days') + ' days)';

            if (obj.Shipment.Package.DeliveryIndicator == 'Y') {
                deliveryDate = moment(obj.Shipment.Package.DeliveryDate, "YYYYMMDD").format('YYYY-MM-DD');
                duration = moment(deliveryDate).diff(createDate, 'days');
                document.getElementById('DeliveryStatus' + trackingNumber).style.color = "green";
                footer = 'Delivered in ' + moment(deliveryDate).to(createDate, 'days');
            } else if (moment().diff(lastUpdate, 'days') > 3) {
                document.getElementById('DeliveryStatus' + trackingNumber).style.color = "red";
            }
        }

        if (document.getElementById('ShippedDate' + trackingNumber)) {
            document.getElementById('ShippedDate' + trackingNumber).innerHTML = createDate;
        }
        document.getElementById('DeliveryStatus' + trackingNumber).innerHTML = lastEvent;
        document.getElementById('DeliveryDays' + trackingNumber).innerHTML = duration;
        document.getElementById('DeliveryDate' + trackingNumber).innerHTML = deliveryDate;

        str = document.getElementById(trackingNumber).innerHTML;
        if (!str.startsWith('<button')) {
            document.getElementById(trackingNumber).innerHTML = '<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#mod' + trackingNumber + '">' + str + '</button>';

            str = '<div id="mod' + trackingNumber + '" class="modal">';
            str += '<div class="modal-dialog modal-lg">';
            str += '<div class="modal-content">';
            str += '<div class="modal-header">';
            str += '<h3>' + trackingNumber + ' (UPS ' + getCarrierService("UPS", trackingNumber, false) + ')</h3>';
            str += '<button type="button" class="close" data-dismiss="modal">&times;</button>';
            str += '</div>';
            str += '<div class="modal-body">';
            str += '<table class="table border small">';
            str += '<thead class="thead-dark">';
            str += '<tr>';
            str += '<th>DATE</th>';
            str += '<th>TIME</th>';
            str += '<th>STATUS</th>';
            str += '<th>LOCATION</th>';
            str += '</tr>';
            str += '</thead>';
            str += '<tbody>';
            str += summary;
            str += detail;
            str += '</tbody>';
            str += '</table>';
            str += '</div>';
            str += '<div class="modal-footer">';
            str += '<p>' + document.getElementById('DeliveryAddress' + trackingNumber).innerHTML + ' - ' + footer + '</p>';
            str += '</div>';
            str += '</div>';
            str += '</div>';
            str += '</div>';

            document.getElementById("modals").innerHTML += str;
        }

        --trackingNumbersToProcess;
        ++trackingNumbersProcessed;
        updateProgressBar(maxTrackingNumbersToProcess, trackingNumbersProcessed);
    };

    xhr.open('POST', configProxyUrl, true);
    xhr.setRequestHeader('Content-Type', 'text/xml');
    xhr.setRequestHeader('Accept-Charset', 'UTF-8,*;q=0.5');
    xhr.setRequestHeader('X-Proxy-URL', configUPSUrl);
    xhr.send(xml);
}

function formatUPSTrackingLine(t) {
    var str = '';

    if (t !== undefined) {
        str = '<tr>';

        str += '<td>' + moment(t.Date, "YYYYMMDD").format('YYYY-MM-DD') + '</td>';

        str += '<td>';
        if (t.Time.length > 0) {
            str += ' ' + moment(t.Time, "HHmmss").format('HH:mm');
        }
        str += '</td>';

        str += '<td>' + t.Status.StatusType.Description + '</td>';

        str += '<td>';
        if (t.ActivityLocation.Address.City !== undefined) {
            str += t.ActivityLocation.Address.City;
            if (t.ActivityLocation.Address.StateProvinceCode !== undefined) {
                str += ", " + t.ActivityLocation.Address.StateProvinceCode;
            }
        }
        str += '</td>';

        str += '</tr>';
    }

    return (str);
}


function connected() {
    var x;

    eBayAuthTokenFlag = true;
    if (!document.getElementById("connected").innerHTML.endsWith("(Connected)")) {
        document.getElementById("connected").innerHTML += " (Connected)";
    }

    x = document.getElementById("startButton");
    x.className = x.className.replace(" btn-danger", " btn-primary");

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

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

    </script>
    <script>includeHTML();</script>

</body>
</html>