Virtonomica: PQR+sort

Цена за единицу качества + сортировка

// ==UserScript==
// @name           Virtonomica: PQR+sort
// @namespace      virtonomica
// @author         mr_Sumkin
// @description    Цена за единицу качества + сортировка
// @include        http*://virtonomic*.*/*/window/unit/supply/create/*/step2
// @include        http*://virtonomic*.*/*/window/unit/equipment/*
// @include        http*://virtonomic*.*/*/main/globalreport/marketing/by_products/*
// @include        http*://virtonomic*.*/*/window/management_units/equipment/buy
// @include        http*://virtonomic*.*/*/window/management_units/equipment/repair
// @require        https://code.jquery.com/jquery-1.11.1.min.js
// @version        1.8
// ==/UserScript==
///// <reference path= "../../_jsHelper/jsHelper/jsHelper.ts" /> 
var Sort;
(function (Sort) {
    Sort[Sort["none"] = 0] = "none";
    Sort[Sort["asc"] = 1] = "asc";
    Sort[Sort["desc"] = 2] = "desc";
})(Sort || (Sort = {}));
;
function run() {
    var Url_rx = {
        v_global_products: /[a-z]+\/main\/globalreport\/marketing\/by_products\/\d+\/?$/i,
        comp_manage_equipment: /\/[a-z]+\/window\/management_units\/equipment\/(?:buy|repair)\/?$/i,
        unit_supply_create: /\/[a-z]+\/unit\/supply\/create\/\d+\/step2\/?$/i,
        unit_equipment: /\/[a-z]+\/window\/unit\/equipment\/\d+\/?$/ig,
    };
    var $ = jQuery;
    var realm = getRealm();
    if (realm == null)
        throw new Error("realm not found");
    // если много страниц то установим макс число на страницу и перезагрузимся
    var $pages = $('ul.pager_list li');
    if ($pages.length > 2) {
        var $pager = $('ul.pager_options li').last();
        var num = $pager.text().trim();
        var pagerUrl = $pager.find('a').attr('href').replace(num, "10000");
        //debugger;
        $.get(pagerUrl, function (data, status, jqXHR) { return location.reload(); });
        return;
    }
    // проверим где мы и вызовем верную функцию
    var path = document.location.pathname;
    if (Url_rx.unit_supply_create.test(path))
        workSupply();
    if (Url_rx.unit_equipment.test(path))
        workEquipment();
    if (Url_rx.comp_manage_equipment.test(path))
        workGroupEquipment();
    if (Url_rx.v_global_products.test(path))
        workProduct();
    function workProduct() {
        var $pqr = $("<div id=\"pqr\" class=\"ordertool\" style=\"cursor: pointer;\">\n                <table class=\"ordercont\">\n                <tbody>\n                    <tr>\n\t                    <td class=\"title-ordertool\">PQR</td>\n\t                    <td class=\"arrows\">\n                            <a id=\"pqrasc\" href=\"#\"><img src=\"/img/asc.gif\" alt=\"^\" width=\"9\" height=\"6\" border=\"0\"></a>\n                            <a id=\"pqrdesc\" href=\"#\"><img src=\"/img/desc.gif\" alt=\"v\" width=\"9\" height=\"6\" border=\"0\"></a>\n                        </td>\n                    </tr>\n                </tbody>\n                </table>\n                <span id=\"sort\" class=\"subvalue\">none</span>\n            </div>");
        $('table.grid th').eq(4).after($pqr.wrapAll("<th></th>").closest("th"));
        var $rows = closestByTagName($('table.grid').find('img[src="/img/supplier_add.gif"]'), "tr");
        // спарсим ряды в объект который будем сортировать. сразу и pqr посчитаем
        var priceSel = function ($r) { return $r.find("td:nth-child(5)"); };
        var qualSel = function ($r) { return $r.find("td:nth-child(4)"); };
        var order = parseRows($rows, priceSel, qualSel);
        // пропихнем везде ячейку со значением pqr
        for (var i = 0; i < order.length; i++)
            priceSel(order[i].$r).after(buildHtmlTD(order[i].place, order[i].pqr));
        $pqr.on("click", function (event) {
            onClick($pqr, event, sort_table);
            return false;
        });
        function sort_table(type) {
            var $start = $("table.grid tr").first();
            order = sortData(order, type);
            var odd = false;
            for (var i = order.length - 1; i >= 0; i--) {
                var $r0 = order[i].$r;
                $r0.removeClass('even odd').addClass(odd ? 'odd' : 'even');
                $start.after($r0);
                odd = odd ? false : true;
            }
        }
    }
    function workEquipment() {
        var $pqr = $("<div id=\"pqr\" class=\"ordertool style=\"cursor: pointer;\">\n                <table class=\"ordercont\" >\n                <tbody>\n                    <tr>\n                        <td class=\"title-ordertool\"> PQR </td>\n                        <td class=\"arrows\">\n                            <a id=\"pqrasc\" href=\"#\"><img src=\"/img/asc.gif\" alt= \"^\" width= \"9\" height= \"6\" border= \"0\"></a>\n                            <a id=\"pqrdesc\" href=\"#\"><img src=\"/img/desc.gif\" alt= \"v\" width= \"9\" height= \"6\" border= \"0\"></a>\n                        </td>\n                    </tr>\n                </tbody>\n                </table>\n                <span id=\"sort\" class=\"add_info\">none</span>\n            </div>");
        // завернем в хедер.
        $('#mainTable th').eq(3).after($pqr.wrapAll("<th rowspan=2></th>").closest("th"));
        var $rows = $('#mainTable').find('tr[id^=r]');
        // спарсим ряды в объект который будем сортировать. сразу и pqr посчитаем
        var priceSel = function ($r) { return $r.find("td:nth-child(8)"); };
        var qualSel = function ($r) { return $r.find("td:nth-child(9)"); };
        var order = parseRows($rows, priceSel, qualSel);
        // пропихнем везде ячейку со значением pqr
        for (var i = 0; i < order.length; i++)
            qualSel(order[i].$r).after(buildHtmlTD(order[i].place, order[i].pqr));
        $pqr.on("click", function (event) {
            onClick($pqr, event, sort_table);
            return false;
        });
        function sort_table(type) {
            var $start = $("#table_header");
            order = sortData(order, type);
            var odd = false;
            for (var i = order.length - 1; i >= 0; i--) {
                var $r0 = order[i].$r;
                $r0.removeClass('even odd').addClass(odd ? 'odd' : 'even');
                $start.after($r0);
                odd = odd ? false : true;
            }
        }
    }
    function workGroupEquipment() {
        var $pqr = $("<div id=\"pqr\" class=\"ordertool\" style=\"cursor: pointer;\">\n                <table class=\"ordercont\">\n                <tbody>\n                    <tr>\n                        <td class=\"title-ordertool\" > PQR </td>\n                        <td class=\"arrows\">\n                            <a id=\"pqrasc\"  href=\"#\"><img src=\"/img/asc.gif\" alt= \"^\" width= \"9\" height= \"6\" border= \"0\" ></a>\n                            <a id=\"pqrdesc\"  href=\"#\"><img src=\"/img/desc.gif\" alt=\"v\" width=\"9\" height=\"6\" border=\"0\"></a>\n                        </td>\n                    </tr>\n                </tbody>\n                </table>\n                <span id=\"sort\" class=\"add_info\">none</span>\n            </div>");
        var $grid = $("form[name='supplyEquipmentForm'] table.list");
        //let $thPrice = $grid.find("th:contains('Цена')");
        //let $thQual = $grid.find("th:contains('Качество')");
        // завернем в хедер.
        $grid.find("th").eq(4).after($pqr.wrapAll("<th></th>").closest("th"));
        var $rows = $grid.find("tr").has("img[src*='unit_types']");
        // спарсим ряды в объект который будем сортировать. сразу и pqr посчитаем
        var priceSel = function ($r) { return $r.find("td:nth-child(5)"); };
        var qualSel = function ($r) { return $r.find("td:nth-child(6)"); };
        var order = parseRows($rows, priceSel, qualSel);
        // пропихнем везде ячейку со значением pqr
        for (var i = 0; i < order.length; i++)
            qualSel(order[i].$r).after(buildHtmlTD(order[i].place, order[i].pqr));
        $pqr.on("click", function (event) {
            onClick($pqr, event, sort_table);
            return false;
        });
        function sort_table(type) {
            var $start = $grid.find("tbody tr").first();
            var sorted = sortData(order, type);
            var odd = false;
            for (var i = sorted.length - 1; i >= 0; i--) {
                var $r0 = sorted[i].$r;
                $r0.removeClass('even odd').addClass(odd ? 'odd' : 'even');
                $start.after($r0);
                odd = odd ? false : true;
            }
        }
    }
    function workSupply() {
        var $pqr = $("     <div id=\"pqr\" class=\"field_title\" style=\"cursor: pointer;\">PQR\n                                <div>\n                                <div class=\"asc\" title=\"\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u043F\u043E \u0432\u043E\u0437\u0440\u0430\u0441\u0442\u0430\u043D\u0438\u044E\">\n                                    <a id=\"pqrasc\" href=\"#\"><img src=\"/img/up_gr_sort.png\"></a>\n                                </div>\n                                <div class=\"desc\" title=\"\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u043F\u043E \u0443\u0431\u044B\u0432\u0430\u043D\u0438\u044E\">\n                                    <a id=\"pqrdesc\" href=\"#\"><img src=\"/img/down_gr_sort.png\"></a>\n                                </div>\n                                <span id=\"sort\" class=\"subvalue\">none</span>\n                                </div>\n                            </div>");
        // завернем в хедер.
        $("table.unit-list-2014 th").eq(4).after($pqr.wrapAll("<th></th>").closest("th"));
        var $rows = $("tr[id^=r]"); // все поставщики имеют id=r4534534 
        // спарсим ряды в объект который будем сортировать. сразу и pqr посчитаем
        var priceSel = function ($r) { return $r.find("td:nth-child(6)"); };
        var qualSel = function ($r) { return $r.find("td:nth-child(7)"); };
        var order = parseRows($rows, priceSel, qualSel);
        // пропихнем везде ячейку со значением pqr
        for (var i = 0; i < order.length; i++)
            qualSel(order[i].$r).after(buildHtmlTD(order[i].place, order[i].pqr));
        $pqr.on("click", function (event) {
            onClick($pqr, event, sort_table);
            return false;
        });
        function sort_table(type) {
            var $start = $("table.unit-list-2014 tbody");
            order = sortData(order, type);
            // вставлять будем задом наперед. Просто начиная с шапки таблицы вставляем в самый верх
            // сначала идут последние постепенно дойдем до первых. Самый быстрый способ вышел
            for (var i = order.length - 1; i >= 0; i--) {
                // если есть заказ, то после строки будет еще аппендикс. его тож надо сортирнуть
                var $r0 = order[i].$r;
                var $append0 = $r0.next('tr.ordered');
                if ($append0.length > 0)
                    $r0 = $r0.add($append0);
                $start.prepend($r0);
            }
        }
    }
    function onClick($pqr, event, sorter) {
        // если кликали на картинку то нам надо взять родительский <a> тег чтобы взять id
        var $el = $(event.target);
        if ($el.is("img"))
            $el = $el.parent(); //
        var type = Sort.none;
        // определим какой тим сортировки надо делать
        if ($el.is("#pqrasc"))
            type = Sort.asc;
        else if ($el.is("#pqrdesc"))
            type = Sort.desc;
        else {
            // если кликали не на стрелки, тада посмотрим какой щас тип сортировки
            if ($pqr.hasClass("asc"))
                type = Sort.desc;
            else if ($pqr.hasClass("desc"))
                type = Sort.none;
            else
                type = Sort.asc;
        }
        // выполним действия
        var $span = $pqr.find("#sort");
        switch (type) {
            case Sort.none:
                $pqr.removeClass("asc desc");
                $span.text("none");
                break;
            case Sort.asc:
                $pqr.removeClass("desc");
                $pqr.addClass("asc");
                $span.text("asc");
                break;
            case Sort.desc:
                $pqr.removeClass("asc");
                $pqr.addClass("desc");
                $span.text("desc");
                break;
        }
        sorter(type);
        return false;
    }
}
;
function parseRows($rows, priceSelector, qualSelector) {
    var res = [];
    for (var i = 0; i < $rows.length; i++) {
        var $r = $rows.eq(i);
        var $price = priceSelector($r);
        var $qual = qualSelector($r);
        if ($price.length !== $qual.length || $price.length !== 1 || $qual.length !== 1)
            alert("Ошибка поиска цены и качества товара в pqr скрипте. Отключите его или исправьте.");
        // в принципе такое может быть что кача нет вообще для пустых складов. Поэтому надо учитывать
        var price = numberfyOrError($price.eq(0).text(), -2);
        var qual = numberfyOrError($qual.eq(0).text(), -2);
        var pqr = (price <= 0 || qual <= 0) ? 0 : (price / qual);
        //$qual.after(buildHtmlTD(i, pqr));
        res.push({ place: i, pqr: pqr, $r: $r });
    }
    return res;
}
function sortData(items, type) {
    switch (type) {
        case Sort.asc:
            items.sort(function (a, b) {
                if (a.pqr > b.pqr)
                    return 1;
                if (a.pqr < b.pqr)
                    return -1;
                return 0;
            });
            break;
        case Sort.desc:
            items.sort(function (a, b) {
                if (a.pqr > b.pqr)
                    return -1;
                if (a.pqr < b.pqr)
                    return 1;
                return 0;
            });
            break;
        case Sort.none:
            items.sort(function (a, b) {
                if (a.place > b.place)
                    return 1;
                if (a.place < b.place)
                    return -1;
                return 0;
            });
    }
    return items;
}
function buildHtmlTD(i, pqr) {
    return "<td id='pqr_" + i + "' class='pqr_data' style='color: blue; width: 70px; text-align: right;'>" + pqr.toFixed(2) + "</td>";
}
function getRealm() {
    // https://*virtonomic*.*/*/main/globalreport/marketing/by_trade_at_cities/*
    // https://*virtonomic*.*/*/window/globalreport/marketing/by_trade_at_cities/*
    var rx = new RegExp(/https:\/\/virtonomic[A-Za-z]+\.[a-zA-Z]+\/([a-zA-Z]+)\/.+/ig);
    var m = rx.exec(document.location.href);
    if (m == null)
        return null;
    return m[1];
}
function closestByTagName(items, tagname) {
    var tag = tagname.toUpperCase();
    var found = [];
    for (var i = 0; i < items.length; i++) {
        var node = items[i];
        while ((node = node.parentNode) && node.nodeName != tag) { }
        ;
        if (node)
            found.push(node);
    }
    return $(found);
}
function numberfy(str) {
    // возвращает либо число полученно из строки, либо БЕСКОНЕЧНОСТЬ, либо -1 если не получилось преобразовать.
    if (String(str) === 'Не огр.' ||
        String(str) === 'Unlim.' ||
        String(str) === 'Не обм.' ||
        String(str) === 'N’est pas limité' ||
        String(str) === 'No limitado' ||
        String(str) === '无限' ||
        String(str) === 'Nicht beschr.') {
        return Number.POSITIVE_INFINITY;
    }
    else {
        // если str будет undef null или что то страшное, то String() превратит в строку после чего парсинг даст NaN
        // не будет эксепшнов
        var n = parseFloat(cleanStr(String(str)));
        return isNaN(n) ? -1 : n;
    }
}
function numberfyOrError(str, minVal, infinity) {
    if (minVal === void 0) { minVal = 0; }
    if (infinity === void 0) { infinity = false; }
    var n = numberfy(str);
    if (!infinity && (n === Number.POSITIVE_INFINITY || n === Number.NEGATIVE_INFINITY))
        throw new RangeError("Получили бесконечность, что запрещено.");
    if (n <= minVal)
        throw new RangeError("Число должно быть > " + minVal);
    return n;
}
function cleanStr(str) {
    return str.replace(/[\s\$\%\©]/g, "");
}
$(document).ready(function () { return run(); });
//# sourceMappingURL=pqr.user.js.map