var $identSerialNoDataTable;
var $identFreeSerialNoDataTable;
var freeSerialNumbersList = [];
var selectedFreeSerialNumbers = [];
var globalIssuedSerialNumbersLocalization;
var globalIssuedSerialNumbersUrls;
var serialNoWarehouseId;
var serialNoIsPOS;

function initializeIssuedSerialNumbers(localization, urls, warehouseId = "WarehouseId", isPOS = false) {
    globalIssuedSerialNumbersLocalization = localization;
    globalIssuedSerialNumbersUrls = urls;
    serialNoWarehouseId = warehouseId;
    serialNoIsPOS = isPOS;

    $('#identSerialNoIssueModal .modal-dialog').draggable();

    $('.partialIdentSerialNoIssueModalContent').resizable({
        alsoResize: ".partialIdentSerialNoIssueModalBody",
        minHeight: 500
    });

    $('#identSerialNoIssueModal').on('show.bs.modal', function () {
        $(this).find('.partialIdentSerialNoIssueModalBody').css({
            'max-height': '95%',
            'min-height': '50%',
            'min-width': '100%'
        });
    });

    $(".partialIdentSerialNoIssueModalContent").resize(function () {
        if ($(".partialIdentSerialNoIssueModalContent").height() > 100) {
            $(".partialIdentSerialNoIssueModalBody").css("height", $(".partialIdentSerialNoIssueModalContent").height() - 80);
            $(".list-free-serials").css("max-height", $(".partialIdentSerialNoIssueModalContent").height() - 320);
        }
        jsRenderDataTable("identSerialNoGridIssue", "partialIdentSerialNoIssueModalBody", 300, true);
        jsRenderDataTable("identFreeSerialNoGrid", "partialIdentSerialNoIssueModalBody", 300, true);
    });

    displayModalByTypeIssue();

    $('#identSerialNoIssueModal').on('hidden.bs.modal', async function (e) {
        isOpen = false;

        if ($("#FiscalStatus").val() > 1 || $("#IsCanceled").val() === "True")
            return;

        if ($("#IdentSerialNoTypeIssue").val() === "P") {
            await deleteUnusedItemSerialsIssue();
        }

        var anNo = toNumber($("#IdentAnNoIssue").val());
        var serialNoQtySum = getSerialNoQtySumIssue();

        $("#quantity-" + anNo).val(toNumber(serialNoQtySum));
        $("#qtyOld-" + anNo).val(toNumber(serialNoQtySum));
        formatNumberInput($("#quantity-" + anNo));

        if (!isPOS) {
            changeIdentData(anNo);
            save();
        } else {
            recalculateItem(anNo);
            onlySave($("#saveButton"));
        }
    });

    var typingTimer;
    var doneTypingInterval = 600;
    $('#identFreeSerialNo').off('keyup');
    $('#identFreeSerialNo').on('keyup', function () {
        clearTimeout(typingTimer);
        typingTimer = setTimeout(function () { getFreeSerialNumbers(); }, doneTypingInterval);
    });
}

var isOpen = false;
function checkIdentSerialNoIssue(anNo, type, serialNo = null, quantity = null, open = null) {
    if (isOpen !== false)
        return;

    serialNo = serialNo ? serialNo : $("#serialNo-" + anNo).val();
    quantity = quantity ? toNumber(quantity) : toNumber($("#quantity-" + anNo).val());

    if ($("#DocTypeSelect option:selected").attr("data-acEnterSn" + serialNo) === "F")
        return;

    $("#IdentSerialNoTypeIssue").val(serialNo);
    $("#InvoiceTypeIssue").val(type);
    $("#IdentAnNoIssue").val(anNo);
    $("#IdentSerialDateDueIssue").val($("#dateDue-" + anNo).val());

    if ((serialNo !== "N" && (quantity > 0 || toNumber($("#qtyOld-" + anNo).val()) > 0)) && open !== "true"
        && ($("#DocTypeSelect option:selected").attr("data-autoInvoSerialNo") === "True" || $("#AutoInvoSerialNo").val() === "True")) {
        isOpen = true;
        serialNoAutoEdition(anNo);
    } else if ((serialNo !== "N" && quantity > 0) || open === "true") {
        isOpen = true;
        openIdentSerialNoIssueModal(toNumber(anNo));
    }
}

function displayModalByTypeIssue() {
    if ($("#IdentSerialNoTypeIssue").val() === "O" || $("#IdentSerialNoTypeIssue").val() === "P") {
        $("#multiplySerialsContainer").addClass("hidden");
    } else {
        $("#multiplySerialsContainer").removeClass("hidden");
    }

    if ($("#IdentSerialNoTypeIssue").val() === "S" || $("#IdentSerialNoTypeIssue").val() === "E") {
        if ($("#IdentSerialDateDueIssue").val() === "true") {
            $(".serialNumberCol").attr('width', "60%");
            $(".dateDue-col").show();
        } else {
            $(".serialNumberCol").attr('width', "76%");
            $(".dateDue-col").hide();
        }
        $(".qty-col").hide();
    } else {
        if ($("#IdentSerialDateDueIssue").val() === "true") {
            $(".serialNumberCol").attr('width', "60%");
            $(".dateDue-col").show();
        } else {
            $(".serialNumberCol").attr('width', "80%");
            $(".dateDue-col").hide();
        }
        $(".qty-col").show();
    }
}

async function openIdentSerialNoIssueModal(anNo) {
    displayModalByTypeIssue();
    $("#identSerialNoIdentIssue").val($("#id-" + anNo).val());
    $("#identSerialNoReqQuantityIssue").val($("#quantity-" + anNo).val());
    $("#identSerialNoPrefixIssue").val("");
    $("#identSerialNoSerialIssue").val(0);
    $("#identSerialNoQtyIssue").val(0);
    await getFreeSerialNumbers();

    if ($("#IdentSerialNoTypeIssue").val() === "P")
        await moveSerialAddSalesIssue(anNo);
    else
        await getSerialNumbersIssueForIdent(anNo);

    if (($("#FiscalStatus").val() > 1 || $("#IsCanceled").val() === "True") && $("#InvoiceTypeIssue").val() === "M") {
        $("#identSerialNoIssueModal :input").prop("disabled", true);
        $("#identSerialNoIssueModal :input").closest("div:not(.form-group)").addClass("document-head-disabled-input");
        $("#identSerialNoIssueModal :button").prop("disabled", true);
    }

    $("#identSerialNoIssueModal").modal("show");
    jsRenderDataTable("identSerialNoGridIssue", "partialIdentSerialNoIssueModalBody", 300, true);
    jsRenderDataTable("identFreeSerialNoGrid", "partialIdentSerialNoIssueModalBody", 300, true);

    var windowWidth = $(window).width();
    if (windowWidth < 481)
        $("#identSerialNoIssueModal .modal-dialog").draggable({ disabled: true });
    else
        $("#identSerialNoIssueModal .modal-dialog").draggable({ disabled: false });
}

async function moveSerialAddSalesIssue(anNo) {
    var data = {
        AcKey: $("#AcKey").val(),
        AnNo: $("#IdentAnNoIssue").val(),
        Ident: $("#identSerialNoIdentIssue").val(),
        Type: "K",
        Column: ""
    };

    await fetch(globalIssuedSerialNumbersUrls.moveSerialNoAddSalesUrl, {
        method: "POST",
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
    }).then((response) => response.json()
    ).then(async (response) => {
        getSerialNumbersIssueForIdent(anNo);
    });
}

async function getSerialNumbersIssueForIdent(anNo) {
    await fetch(globalIssuedSerialNumbersUrls.getByAcKeyAndAnNoUrl + "?acKey=" + $("#AcKey").val() + "&anNo=" + anNo, {
        method: "GET",
        headers: { 'Content-Type': 'application/json' }
    }).then((response) => response.json()
    ).then(async (data) => {
        $('#identSerialNoGridIssue tbody tr').remove();
        var qty = 0;
        if (data && data.length) {
            for (var i = 0; i < data.length; i++) {
                addSerialNumberIssueRow(data[i].SerialNo, data[i].Qty, null, data[i].DateDue, data[i].AnQid);
                qty = qty + data[i].Qty;
            }
        }

        $("#identSerialNoQuantityIssue").val(qty);
        $("#identSerialNoDifferenceIssue").val(Math.abs(toNumber($("#identSerialNoReqQuantityIssue").val())) - toNumber($("#identSerialNoQuantityIssue").val()));
        formatNumberInput($("#identSerialNoQuantityIssue"));
        formatNumberInput($("#identSerialNoDifferenceIssue"));
    });
}

function addSerialNumberIssueRow(serialNo, qty, oldQty = null, dateDue, anQid) {
    var id = anQid ? anQid : 0;;
    var isQtyHidden = $("#IdentSerialNoTypeIssue").val() === "S" || $("#IdentSerialNoTypeIssue").val() === "E" ? true : false;
    var isDateDueHidden = $("#IdentSerialDateDueIssue").val() === "true" ? false : true;
    var isDisabled = $("#FiscalStatus").val() > 1 ? true : false;

    $('#identSerialNoGridIssue > tbody:last-child').append(
        '<tr id="tr-serial-' + id + '" class="sortable-row">' +
        '<td class="serial-numbers-td"><input id="identSerialNoIssue-' + id + '" class="form-control border-bottom-none serialNoCodeIssue" value="' + serialNo + '" disabled /><input id="identSerialNoQidIssue-' + id + '" value="' + id + '" class="serialNoQidIssue" hidden disabled /></td>' +
        '<td class="serial-numbers-td qty-col ' + (isQtyHidden ? "hidden" : "") + '"><input class="form-control border-bottom-none serialNoQtyIssue" id="serialNoQtyIssue-' + id + '" value="' + qty + '" onchange="saveSerialNoIssue(\'' + id + '\')" />' +
        '<input id="savedSerialNoQtyIssue-' + id + '" value="' + (oldQty !== null ? oldQty : qty) + '" hidden/></td>' +
        '<td class="serial-numbers-td dateDue-col ' + (isDateDueHidden ? "hidden" : "") + '"><input class="form-control border-bottom-none datepicker serialNoDateDueIssue" id="serialNoDateDueIssue-' + id + '" value="' + dateDue + '" onchange="saveSerialNoIssue(\'' + id + '\')" />' +
        '<input id="savedSerialNoDateDueIssue-' + id + '" class="datepicker" value="' + dateDue + '" hidden/></td>' +
        '<td class="td-action"><button type="button" onclick="deleteSerialNoIssue(\'' + id + '\')" class="btn btn-link editableInput" ' + (isDisabled ? "disabled" : "") + '><span class="far fa-trash-alt"></span></button></td>' +
        '</tr>'
    );

    $('#serialNoDateDueIssue-' + id).datepicker()
        .on('click', function (e) {
            $(this).select();
        }).on('changeDate', function () {
            $(this).datepicker('hide');
        });
}

async function saveSerialNoIssue(anQid = null) {
    var id = anQid;
    var serialNo = $("#identSerialNoIssue-" + anQid).val();
    var $serialCodes = $(".serialNoCodeIssue");

    if ($serialCodes && $serialCodes.length) {
        for (var i = 0; i < $serialCodes.length; i++) {
            if ($serialCodes[i].value === $("#input-serial-no").val()) {
                $().customModal({
                    destroyOnClose: true,
                    showCloseButton: true,
                    type: "error",
                    text: globalIssuedSerialNumbersLocalization.errorSaving,
                    buttons: [
                        {
                            icon: 'fa fa-check',
                            text: globalIssuedSerialNumbersLocalization.confirm,
                            closeOnAction: true,
                            type: 'primary'
                        }
                    ]
                });

                return;
            }
        }
    }

    var serialNoQtySum = getSerialNoQtySumIssue();
    if (!serialNo)
        serialNoQtySum = serialNoQtySum + toNumber($("#input-serial-quantity").val());

    serialNo = serialNo ? serialNo : $("#input-serial-no").val();
    serialNoDateDueIssue = $("#serialNoDateDueIssue-" + id).val() ? $("#serialNoDateDueIssue-" + id).datepicker("getDate") : $("#input-serial-dateDue").datepicker("getDate");

    var data = {
        AcKey: $("#AcKey").val(),
        AnNo: $("#IdentAnNoIssue").val(),
        Issuer: $("#" + serialNoWarehouseId).val(),
        Ident: $("#identSerialNoIdentIssue").val(),
        SerialNo: serialNo,
        Quantity: serialNoQtySum,
        QuantityOld: $("#savedSerialNoQtyIssue-" + id).val() ? $("#savedSerialNoQtyIssue-" + id).val() : 0,
        QuantityNew: $("#serialNoQtyIssue-" + id).val() ? $("#serialNoQtyIssue-" + id).val() : $("#input-serial-quantity").val(),
        DateDueNew: $("#IdentSerialDateDueIssue").val() === "true" ? serialNoDateDueIssue : null,
        DateDue: $("#IdentSerialDateDueIssue").val() === "true" && $("#savedSerialNoDateDueIssue-" + id).val() ? $("#savedSerialNoDateDueIssue-" + id).datepicker("getDate") : null,
        Type: $("#SerialNoMoveTypeIssue").val(),
        SNWOType: $("#SerialNoWOTypeIssue").val(),
        Package: "",
        PackQty: 0,
        InvoiceType: $("#InvoiceTypeIssue").val()
    };

    if (toNumber(serialNoQtySum) === Math.abs(toNumber($("#identSerialNoReqQuantityIssue").val()))) {
        $().customModal({
            destroyOnClose: true,
            showCloseButton: true,
            type: "success",
            text: globalIssuedSerialNumbersLocalization.serialNumberQuantityIsReached,
            buttons: [
                {
                    icon: 'fa fa-check',
                    text: globalIssuedSerialNumbersLocalization.confirm,
                    closeOnAction: true,
                    type: 'primary'
                }
            ]
        });
    }

    await fetch(globalIssuedSerialNumbersUrls.moveUpdateSerialNoUrl, {
        method: "POST",
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
    }).then((response) => response.json()
    ).then(async (response) => {
        if (!response || response === false) {
            $().customModal({
                destroyOnClose: true,
                showCloseButton: true,
                type: "alert",
                text: globalIssuedSerialNumbersLocalization.errorSaving,
                buttons: [
                    {
                        icon: 'fa fa-check',
                        text: globalIssuedSerialNumbersLocalization.confirm,
                        closeOnAction: true,
                        type: 'primary'
                    }
                ]
            });
        } else {
            if ($("#input-serial-no").val()) {
                var lastQid = $("#identSerialNoGridIssue input.serialNoQidIssue:last").val();
                addSerialNumberIssueRow($("#input-serial-no").val(), $("#input-serial-quantity").val(), null, null, lastQid ? toNumber(lastQid) + 1 : 0);
                $("#input-serial-no").val("");
                $("#input-serial-quantity").val(1);
            } else {
                $("#savedSerialNoQtyIssue-" + id).val(data.QuantityNew);
                $("#savedSerialNoDateDueIssue-" + id).val(data.DateDueNew);
                $("#savedSerialNoDateDueIssue-" + id).datepicker("setDate", data.DateDueNew);
                $("#identSerialNoQuantityIssue").val(0);
                addReqQuantityIssue(getSerialNoQtySumIssue());
            }

            await getFreeSerialNumbers();
        }
    });
}

function onMultiplySerialNumberIssue() {
    var serialNoQtySum = getSerialNoQtySumIssue();
    if ((serialNoQtySum + toNumber($("#identSerialNoQtyIssue").val())) > toNumber($("#identSerialNoReqQuantityIssue").val())) {
        $().customModal({
            title: "",
            destroyOnClose: true,
            showCloseButton: true,
            type: "question",
            text: globalIssuedSerialNumbersLocalization.numberOfSerialNumbersIsGreaterThanOnDocument,
            buttons: [
                {
                    icon: 'fa fa-times',
                    text: globalIssuedSerialNumbersLocalization.cancel,
                    closeOnAction: true,
                    type: 'ghost'
                },
                {
                    icon: 'fa fa-check',
                    text: globalIssuedSerialNumbersLocalization.confirm,
                    action: async function () {
                        multiplySerialNumbersIssue();
                    },
                    closeOnAction: true,
                    type: 'primary'
                }
            ]
        });
    } else
        multiplySerialNumbersIssue();
}

async function multiplySerialNumbersIssue() {
    if ($("#identSerialNoQtyIssue").val() > 0) {
        $("#multiplySerialsBtn").find("i").addClass("fa-spinner fa-spin");
        $("#multiplySerialsBtn").prop("disabled", true);

        var serialNoQtySum = getSerialNoQtySumIssue();
        var serial = $("#identSerialNoSerialIssue").val();
        var serialLength = serial.length;

        for (var i = 0; i < $("#identSerialNoQtyIssue").val(); i++) {
            var freeSerialExists = freeSerialNumbersList.some(function (item) {
                return item.SerialNo === ($("#identSerialNoPrefixIssue").val() + serial);
            });

            if ($("#InvoiceTypeIssue").val() === "M" && !freeSerialExists) {
                $().customModal({
                    destroyOnClose: true,
                    showCloseButton: true,
                    type: "alert",
                    text: stringFormat(globalIssuedSerialNumbersLocalization.selectedSerialNumberDoesNotExistInWarehouse, $("#identSerialNoPrefixIssue").val() + serial),
                    buttons: [
                        {
                            icon: 'fa fa-check',
                            text: globalIssuedSerialNumbersLocalization.confirm,
                            closeOnAction: true,
                            type: 'primary'
                        }
                    ]
                });

                $("#multiplySerialsBtn").find("i").removeClass("fa-spinner fa-spin");
                $("#multiplySerialsBtn").prop("disabled", false);
                return;
            }

            var data = {
                AcKey: $("#AcKey").val(),
                AnNo: $("#IdentAnNoIssue").val(),
                Issuer: $("#" + serialNoWarehouseId).val(),
                Ident: $("#identSerialNoIdentIssue").val(),
                SerialNo: $("#identSerialNoPrefixIssue").val() + serial,
                Quantity: serialNoQtySum,
                QuantityOld: 0,
                QuantityNew: $("#IdentSerialNoTypeIssue").val() === "S" || $("#IdentSerialNoTypeIssue").val() === "E" ? 1 : 0,
                Type: $("#SerialNoMoveTypeIssue").val(),
                SNWOType: $("#SerialNoWOTypeIssue").val(),
                Package: "",
                PackQty: 0,
                InvoiceType: $("#InvoiceTypeIssue").val()
            };

            await fetch(globalIssuedSerialNumbersUrls.serialNoUpdUrl, {
                method: "POST",
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(data)
            }).then((response) => response.json()
            ).then(async (response) => {
                if (!response || response === false) {
                    $().customModal({
                        destroyOnClose: true,
                        showCloseButton: true,
                        type: "alert",
                        text: globalIssuedSerialNumbersLocalization.errorSaving,
                        buttons: [
                            {
                                icon: 'fa fa-check',
                                text: globalIssuedSerialNumbersLocalization.confirm,
                                closeOnAction: true,
                                type: 'primary'
                            }
                        ]
                    });
                } else {
                    var lastQid = $("#identSerialNoGridIssue input.serialNoQidIssue:last").val();
                    addSerialNumberIssueRow($("#identSerialNoPrefixIssue").val() + serial, data.QuantityNew, null, null, lastQid ? toNumber(lastQid) + 1 : 0);
                    await getFreeSerialNumbers();

                    if (data.QuantityNew > 0)
                        addReqQuantityIssue(data.QuantityNew);
                }
            });

            serial = pad(toNumber(serial) + 1, serialLength);
        }

        $("#multiplySerialsBtn").find("i").removeClass("fa-spinner fa-spin");
        $("#multiplySerialsBtn").prop("disabled", false);
    }
}

async function deleteSerialNoIssue(anQid) {
    var data = {
        AcKey: $("#AcKey").val(),
        AnNo: $("#IdentAnNoIssue").val(),
        SerialNo: $("#identSerialNoIssue-" + anQid).val(),
        Receiver: $("#" + serialNoWarehouseId).val(),
        Ident: $("#identSerialNoIdentIssue").val(),
        Quantity: toNumber($("#serialNoQtyIssue-" + anQid).val()),
        QuantityOld: 0,
        QuantityNew: toNumber($("#serialNoQtyIssue-" + anQid).val()),
        Date: $("#InvoiceTypeIssue").val() === "M" ? $("#InvoiceDate").datepicker("getDate") : $("#Date").datepicker("getDate"),
        DateDueNew: $("#IdentSerialDateDueIssue").val() === "true" && $("#serialNoDateDueIssue-" + anQid).val() ? $("#serialNoDateDueIssue-" + anQid).datepicker("getDate") : null,
        DateDue: $("#IdentSerialDateDueIssue").val() === "true" && $("#savedSerialNoDateDueIssue-" + anQid).val() ? $("#savedSerialNoDateDueIssue-" + anQid).datepicker("getDate") : null,
        InvoiceType: $("#InvoiceTypeIssue").val(),
        SNType: $("#IdentSerialNoTypeIssue").val()
    };

    await fetch(globalIssuedSerialNumbersUrls.deleteIssuedByAcKeyAndSerialNo, {
        method: "POST",
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
    }).then((response) => response.json()
    ).then((data) => {
        if (data && data === true) {
            addReqQuantityIssue(toNumber($("#serialNoQtyIssue-" + anQid).val()), true);
            $("#tr-serial-" + anQid).remove();

            var serialNoQtySum = getSerialNoQtySumIssue();
            if (toNumber(serialNoQtySum) === Math.abs(toNumber($("#identSerialNoReqQuantityIssue").val()))) {
                $().customModal({
                    destroyOnClose: true,
                    showCloseButton: true,
                    type: "success",
                    text: globalIssuedSerialNumbersLocalization.serialNumberQuantityIsReached,
                    buttons: [
                        {
                            icon: 'fa fa-check',
                            text: globalIssuedSerialNumbersLocalization.confirm,
                            closeOnAction: true,
                            type: 'primary'
                        }
                    ]
                });
            }

            getFreeSerialNumbers();
        }
    });
}

async function deleteAllSerialsIssue() {
    var data = {
        AcKey: $("#AcKey").val(),
        AnNo: $("#IdentAnNoIssue").val(),
        Receiver: $("#" + serialNoWarehouseId).val(),
        Ident: $("#identSerialNoIdentIssue").val(),
        Date: $("#InvoiceTypeIssue").val() === "M" ? $("#InvoiceDate").datepicker("getDate") : $("#Date").datepicker("getDate"),
        InvoiceType: $("#InvoiceTypeIssue").val(),
        SNType: $("#IdentSerialNoTypeIssue").val()
    };

    await fetch(globalIssuedSerialNumbersUrls.deleteAllIssuedByAcKey, {
        method: "POST",
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
    }).then((response) => response.json()
    ).then((data) => {
        if (data && data === true) {
            $('#identSerialNoGridIssue tbody tr').remove();
            $("#identSerialNoQuantityIssue").val(0);
            addReqQuantityIssue(0);

            getFreeSerialNumbers();
        }
    });
}

async function deleteUnusedItemSerialsIssue() {
    await fetch(globalIssuedSerialNumbersUrls.deleteUnusedItemSerialsUrl + "?acKey=" + $("#AcKey").val() + "&anNo=" + $("#IdentAnNoIssue").val() + "&type=" + "K" + "&invoiceType=" + $("#InvoiceTypeIssue").val(), {
        method: "GET",
        headers: { 'Content-Type': 'application/json' }
    }).then((response) => response.json()
    ).then(async (data) => {
        if (data && data === true) {
            var items = $(".serialNoQtyIssue");
            for (var i = 0; i < items.length; i++) {
                if (items[i].value === 0) {
                    items[i].closest("tr").remove();
                }
            }
        }
    });
}

function addReqQuantityIssue(qty, isRemove = null) {
    if (isRemove)
        $("#identSerialNoQuantityIssue").val(toNumber($("#identSerialNoQuantityIssue").val()) - qty);
    else
        $("#identSerialNoQuantityIssue").val(toNumber($("#identSerialNoQuantityIssue").val()) + qty);

    $("#identSerialNoDifferenceIssue").val(toNumber($("#identSerialNoReqQuantityIssue").val()) - toNumber($("#identSerialNoQuantityIssue").val()));
    formatNumberInput($("#identSerialNoReqQuantityIssue"));
    formatNumberInput($("#identSerialNoQuantityIssue"));
    formatNumberInput($("#identSerialNoDifferenceIssue"));
}

function getSerialNoQtySumIssue() {
    var serialNoQtySum = 0;
    var $qtyElements = $(".serialNoQtyIssue");
    if ($qtyElements && $qtyElements.length) {
        for (var i = 0; i < $qtyElements.length; i++) {
            serialNoQtySum = serialNoQtySum + toNumber($qtyElements[i].value);
        }
    }
    return toNumber(serialNoQtySum);
}

async function getFreeSerialNumbers() {
    $.ajax({
        type: "POST",
        data: JSON.stringify({
            ident: $("#identSerialNoIdentIssue").val(),
            anNo: $("#IdentAnNoIssue").val(),
            warehouse: $("#" + serialNoWarehouseId).val(),
            search: $("#identFreeSerialNo").val(),
            searchSerialNoDueDate: $("#IdentLookupSearchSerialNoDueDate").val() === "True" && $("#IdentSerialDateDueIssue").val() === "true"
        }),
        url: globalIssuedSerialNumbersUrls.getFreeSerialNumbers,
        contentType: "application/json"
    }).done(function (response) {
        loadFreeSerialNumbers(response);
    });
}

function loadFreeSerialNumbers(freeSerialNumbers) {
    selectedFreeSerialNumbers = [];
    freeSerialNumbersList = freeSerialNumbers;

    $identFreeSerialNoDataTable = $('#identFreeSerialNoGrid');
    if ($.fn.dataTable.isDataTable('#identFreeSerialNoGrid'))
        $identFreeSerialNoDataTable.DataTable().destroy();

    $identFreeSerialNoDataTable.DataTable({
        serverSide: false,
        ajax: undefined,
        scroller: false,
        responsive: false,
        paging: false,
        info: false,
        data: freeSerialNumbers,
        columns: [
            {
                data: "",
                className: 'dt-body-center',
                render: function (data, type, full) {
                    return '<input class="ackey" onclick="selectedFreeSerialNumber(\'' + full.SerialNo + '\', \'' + full.Warehouse + '\', \'' + full.Stock + '\', \'' + full.DateDue + '\', \'' + full.AnQid + '\')" type="checkbox" />';
                }
            },
            { data: "SerialNo" },
            { data: "Stock", visible: $("#IdentSerialNoTypeIssue").val() === "E" || $("#IdentSerialNoTypeIssue").val() === "S" ? false : true },
            { data: "DateDue", visible: $("#IdentSerialDateDueIssue").val() === "true" ? true : false }
        ],
        initComplete: function (settings, json) {
            //$(".partialIdentSerialNoIssueModalContent").trigger("resize");
        }
    });
}

function selectedFreeSerialNumber(serialNo, warehouse, qty, dateDue, anQid) {
    qty = toNumber(qty);
    var index = selectedFreeSerialNumbers.findIndex(x => x.SerialNo === serialNo && x.Warehouse === warehouse);

    var selectedQtySum = selectedFreeSerialNumbers.reduce(function (s, a) {
        return toNumber(s + a.Qty);
    }, 0);

    if ($("#IdentSerialNoTypeIssue").val() === "E" || $("#IdentSerialNoTypeIssue").val() === "S")
        qty = 1;
    else {
        if (qty <= (toNumber($("#identSerialNoDifferenceIssue").val()) - toNumber(selectedQtySum)) || selectedQtySum >= toNumber($("#identSerialNoDifferenceIssue").val()))
            qty = qty;
        else if (qty > (toNumber($("#identSerialNoDifferenceIssue").val()) - selectedQtySum) && toNumber($("#identSerialNoDifferenceIssue").val()) > 0 && toNumber($("#identSerialNoDifferenceIssue").val()) > selectedQtySum)
            qty = toNumber($("#identSerialNoDifferenceIssue").val()) - selectedQtySum;
        else
            qty = 1;
    }

    if (index !== -1)
        selectedFreeSerialNumbers.splice(index, 1);
    else
        selectedFreeSerialNumbers.push({ SerialNo: serialNo, Warehouse: warehouse, Qty: qty, DateDue: dateDue, AnQid: anQid });
}

async function transferSelectedFreeSerialNumbers() {
    $("#transferSerialNumbersBtn").find("i").addClass("fa-spinner fa-spin");
    $("#transferSerialNumbersBtn").prop("disabled", true);

    var selectedFreeSN = selectedFreeSerialNumbers;
    for (var i = 0; i < selectedFreeSN.length; i++) {
        let item = selectedFreeSN[i];
        var currDate = (new Date()).toISOString().split('T')[0];
        if ($("#IdentSerialDateDueIssue").val() === "true" && new Date(reformatDate(selectedFreeSN[i].DateDue)) < new Date(currDate)) {
            await new Promise((resolve) => setTimeout(function () {
                $().customModal({
                    destroyOnClose: true,
                    showCloseButton: true,
                    type: "success",
                    text: globalIssuedSerialNumbersLocalization.dateDueExpiredForSerialNumber + " " + selectedFreeSN[i].SerialNo,
                    buttons: [
                        {
                            icon: 'fa fa-check',
                            text: $("#ConfirmLoc").val(),
                            action: async function () {
                                await transferSerialNumbersPOST(item, selectedFreeSN.length);
                                resolve();
                            },
                            closeOnAction: true,
                            type: 'primary'
                        }
                    ]
                });
            }, 1000));
        } else
            await transferSerialNumbersPOST(item, selectedFreeSN.length);
    }

    await getFreeSerialNumbers();
    $("#transferSerialNumbersBtn").find("i").removeClass("fa-spinner fa-spin");
    $("#transferSerialNumbersBtn").prop("disabled", false);
}

async function transferSerialNumbersPOST(selectedFreeSerialNo, serialsLength) {
    var serialAlreadyExists = false;
    var $serialCodes = $(".serialNoCodeIssue");
    if ($serialCodes && $serialCodes.length) {
        for (var c = 0; c < $serialCodes.length; c++) {
            if ($serialCodes[c].value.trim() === selectedFreeSerialNo.SerialNo.trim()) {
                serialAlreadyExists = true;
            }
        }
    }

    if (serialAlreadyExists) {
        if ($("#IdentSerialNoTypeIssue").val() === "K" || $("#IdentSerialNoTypeIssue").val() === "O" || $("#IdentSerialNoTypeIssue").val() === "P") {
            $("#serialNoQtyIssue-" + selectedFreeSerialNo.AnQid).val(toNumber($("#serialNoQtyIssue-" + selectedFreeSerialNo.AnQid).val()) + 1);
            saveSerialNoIssue(selectedFreeSerialNo.AnQid);
            addReqQuantityIssue(1);

            if (i === serialsLength - 1) {
                await getFreeSerialNumbers();
                $("#transferSerialNumbersBtn").find("i").removeClass("fa-spinner fa-spin");
                $("#transferSerialNumbersBtn").prop("disabled", false);
            }
        }
        return;
    }

    var data = {
        AcKey: $("#AcKey").val(),
        AnNo: $("#IdentAnNoIssue").val(),
        Issuer: $("#" + serialNoWarehouseId).val(),
        Ident: $("#identSerialNoIdentIssue").val(),
        SerialNo: selectedFreeSerialNo.SerialNo,
        Qty: selectedFreeSerialNo.Qty,
        DateDue: selectedFreeSerialNo.DateDue,
        Type: $("#SerialNoMoveTypeIssue").val(),
        SNWOType: $("#SerialNoWOTypeIssue").val(),
        Package: "",
        PackQty: 0,
        InvoiceType: $("#InvoiceTypeIssue").val()
    };

    await fetch(globalIssuedSerialNumbersUrls.createSerialNoUrl, {
        method: "POST",
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
    }).then((response) => response.json()
    ).then(async (response) => {
        if (!response || response === false) {
            $().customModal({
                destroyOnClose: true,
                showCloseButton: true,
                type: "alert",
                text: globalIssuedSerialNumbersLocalization.errorSaving,
                buttons: [
                    {
                        icon: 'fa fa-check',
                        text: globalIssuedSerialNumbersLocalization.confirm,
                        closeOnAction: true,
                        type: 'primary'
                    }
                ]
            });
        } else {
            addSerialNumberIssueRow(selectedFreeSerialNo.SerialNo, selectedFreeSerialNo.Qty, 0, selectedFreeSerialNo.DateDue, selectedFreeSerialNo.AnQid);
            await saveSerialNoIssue(selectedFreeSerialNo.AnQid);
        }
    });
}

async function serialNoAutoEdition(anNo) {
    var data = {
        AcKey: $("#AcKey").val(),
        DocType: $("#DocType").val(),
        AnNo: $("#IdentAnNoIssue").val(),
        Issuer: $("#" + serialNoWarehouseId).val(),
        Ident: $("#id-" + anNo).val(),
        QuantityOld: $("#qtyOld-" + anNo).val(),
        QuantityNew: $("#quantity-" + anNo).val(),
        Type: "K"
    };

    await fetch(globalIssuedSerialNumbersUrls.serialNoAutoEditionUrl, {
        method: "POST",
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
    }).then((response) => response.json()
    ).then(async (response) => {
        if (toNumber($("#quantity-" + anNo).val()) > toNumber(response.KolicSN)) {
            let err = globalIssuedSerialNumbersLocalization.automaticIssueOfSerialNumbersNotPossible + "<br>"
                + globalIssuedSerialNumbersLocalization.desiredQuantity + ": " + formatDisplay("2", $("#quantity-" + anNo).val()) + "<br>"
                + globalIssuedSerialNumbersLocalization.actualQuantity + ": " + formatDisplay("2", response.KolicSN) + "<br>"
                + globalIssuedSerialNumbersLocalization.difference + ": " + formatDisplay("2", toNumber($("#quantity-" + anNo).val()) - toNumber(response.KolicSN));

            $().customModal({
                destroyOnClose: true,
                showCloseButton: true,
                type: "success",
                text: err,
                buttons: [
                    {
                        icon: 'fa fa-check',
                        text: globalIssuedSerialNumbersLocalization.confirm,
                        action: async function () {
                            isOpen = false;
                            checkIdentSerialNoIssue(anNo, "M", null, null, "true");
                        },
                        closeOnAction: true,
                        type: 'primary'
                    }
                ]
            });
        }

        $("#quantity-" + anNo).val(toNumber(response.KolicSN));
        $("#qtyOld-" + anNo).val(toNumber(response.KolicSN));
        formatNumberInput($("#quantity-" + anNo));
    });
}