/* $Revision$ $Id$ File: sel_items_tab.js Description: Javascript code om client-side de HTML tabel met bestelitems te vullen Bij bestaande bestellingen maakt AddAllItems alle regels aan uit details_Items (gevuld in details.inc) Bij nieuwe bestellingen worden regels 1 voor 1 toegevoegd via AddItem Parameters: Context: Note: Op het TR-element stoppen wel allerlei informatie (die vroeger in selectedItems zat) tr.bes_item_info: van alles over het item amount: huidige aantal orgAmount: oorspronkelijke aantal retour: received: */ var lastsrtgroup_text = ""; function AddAllItems(editable, show_received) { if (this.details_Items == null) return; var table = $("#sel_items>tbody")[0]; for (i in details_Items) { if (details_Items[i].srtgroup_text != lastsrtgroup_text) { var tr = table.insertRow(-1); tr.className = "bessrtgroepname"; var cell = tr.insertCell(-1); cell.colSpan = 8 + (window.fotomode==1?1:0) + (show_received?1:0) - (hide_cost?3:0); $(cell).text(details_Items[i].srtgroup_text) } lastsrtgroup_text = details_Items[i].srtgroup_text; CreateRow(details_Items[i], details_Items[i].amount, (show_received? details_Items[i].received : -1), editable, details_Items[i].objFlex); } if (editable) StaffelKortingResult(); FcltMgr.resized(); } function RetourItems(bes_key, urole) { var s = "../bes/bes_retour.asp?bes_key=" + bes_key + "&urole="+ urole; FcltMgr.openModalDetail(s, L("lcl_bes_retour"), {callback: FcltMgr.reload}); } window.bes_item_info = null; // forceer global scope function load_item_info(srtdeel_key, urole, aantal, bes_key) { if (window.bes_item_info && window.bes_item_info.srtdeel_key == srtdeel_key) return; // Laad de gegevens van het artikel. if (srtdeel_key == -1) { window.bes_item_info = null; } else { // NB: bes_key bestaat niet voor een nieuwe bestelling! bes_key = (bes_key ? bes_key : -1); checkXhrObj[bes_key] = (checkXhrObj[bes_key] ? checkXhrObj[bes_key] : {}); checkXhrObj[bes_key][srtdeel_key] = true; $.getJSON("get_item_info_ajax.asp?srtdeel_key=" + srtdeel_key + "&bes_key=" + bes_key, async function(data) { window.bes_item_info = data; // forceer global scope show_item_details(window.bes_item_info); // Indien artikelgroep niet is ingevuld, dan deze nog even invullen. // PNBR#23071: Artikelgroep NIET invullen als artikel rechtstreeks in listbox gekozen is. if (data.singlegroep && $("#srtgroep").val() == -1) { sgSrtgroep.setValue(data.srtgroup_key, data.srtgroup_text, false, false, data.singlegroep, true) } checkXhrObj[bes_key][srtdeel_key] = false; if (aantal && aantal > 0) { if (window.details_Items != null) { // Als de gegevens er al staan dan niet nogmaals toevoegen for (var x in details_Items) { if (details_Items[x].srtdeel_key === srtdeel_key) { return; } } } await AddSuggestItem(data, aantal, urole); } } ) } } function getAantalArtikelen() { // Hoeveel artikelen zijn er al geselecteerd return $("#sel_items>tbody>tr").not(".bessrtgroepname").length; } function maxArtikelReached() { var aantalArtikelen = getAantalArtikelen(); return (maxartikel > 0 && aantalArtikelen >= maxartikel) } var jqFreeFields = ["lev_key_show", "srtdeel_nr", "omschrijving", "srtgroep", "price", "btw", "aantal_text"]; async function AddFreeArticleItem(urole) { if (!await validateForm("u2", { checkOnly: jqFreeFields })) return; window.bes_item_info = { aantal: parseFloat($('#aantal_text').val().replace(",", ".")), isFreeArticle: true, "srtdeel_key":-1, "srtdeel_nr":$('#srtdeel_nr').val(), "srtdeel_omschrijving":$('#omschrijving').val(), //"srtgroup_key":$("#srtgroep").val(), //"srtgroup_text":$("#srtgroep_show").val(), "lev_key":$("#lev_key").val(), //"lev_name":$("#lev_key_show").attr("sgCurrentValue"), "singlegroep":0, //"srtdeel_image":"https://cos.euroflorist.com/uwv/Products/ARR06_03.jpg", "veelvoud": 1, "price":parseFloat(String($("#price").val()).replace(',', '.')) || 0.0, "btw":parseFloat(String($("#btw").val()).replace(',', '.')), "eenheid":$("#unit").val(), "num_prop":0, "staffelgroep":-1, "bestelminimum":0, "bestelmaximum":-1, //"opmerking":"Prijs inclusief bezorgkosten" "auth": { canWriteBESBOF: 0 } } AddItem(bes_item_info, window.bes_item_info.aantal, urole, true); $("#lev_key_show").prop('disabled', true); // Maximaal één leverancier } async function AddSuggestItem(bes_item_info, aantal, urole) { if (!bes_item_info || bes_item_info.srtdeel_key < 0) { FcltMgr.alert(L("lcl_shared_choose_item_first")); return; } if (!window.is_correctie) { // Als flexkenmerken met prs-sql in default dan moet de persoon minimaal ingevuld zijn. if (bes_item_info.num_prssql > 0 && !await validateForm("u2", { checkOnly: ["person_show"] })) return false; // Is er geen conflict tussen de voorraad, bestelveelvoud en bestelminimum als maxbestel == 1? if (window.stock_info.maxbestel == 1) { var stock_veelvoud = window.stock_info.stock - (window.stock_info.stock % bes_item_info.veelvoud); if (window.stock_info.stock < bes_item_info.bestelminimum || stock_veelvoud < bes_item_info.bestelminimum) { FcltMgr.alert(L("lcl_bes_stock_too_low")); return false; } } if (window.stock_info.stock == 0) FcltMgr.alert(L("lcl_bes_out_of_stock")); else if (window.stock_info.stock && aantal > window.stock_info.stock) { if (window.stock_info.maxbestel == 1) { aantal = window.stock_info.stock; // Aantal verlagen naar het aantal dat in voorraad is. FcltMgr.alert(L("lcl_bes_reduced_to_max").format(aantal, aantal)); } else FcltMgr.alert(L("lcl_bes_exceed_stock")); } } AddItem(bes_item_info, aantal, urole, true); } function AddItem(bes_item_info, aantal, urole, doCheckAmount) { // openModalDetail is dan wel modal maar niet synchroon, daarom continueAdd callback var continueAdd = function(objFlex) { if (objFlex) { bes_item_info.auth = (bes_item_info.auth ? bes_item_info.auth : {}); // Als bes_item_info.auth nog niet bestaat dan deze nu alsnog aanmaken. bes_item_info.auth.canWriteBESBOF = (objFlex && objFlex[5] ? objFlex[5].canWriteBESBOF : 0); } if (bes_item_info.num_prop > 0 && !objFlex) return; // geen flex ingevuld var aantal_cell = CreateRow(bes_item_info, aantal, -1, true, objFlex, urole); if (doCheckAmount) { var vdata = { voorraad: parseFloat(window.stock_info.stock) , maxbestel: parseInt(window.stock_info.maxbestel, 10) }; checkAmount(aantal_cell, vdata); // eventuele minimum en zo } StaffelKortingResult(); // Indien singlegroep is gezet kunnen binnen een catalogus uitsluitend artikelen uit dezelfde groep worden besteld. Alle artikelen in de bestellijst moeten dan uit dezelfde groep komen. // Indien er minstens één bestelregels aanwezig is mag de artikelgroep niet meer worden gewijzigd. if ($("#singlegroep").val() == 1) { $("#srtgroep_show")[0].style.display = "none"; $("#srtgroep_ro").val($("#srtgroep_show").val()); $("#srtgroep_ro")[0].style.display = "block"; } // Item veld en details van item wissen: onChangeArtikelgroep does the trick if (!bes_item_info.isFreeArticle) onChangeArtikelgroep(); else { $('#aantal_text').val(""); $('#srtdeel_nr').val(""); $('#omschrijving').val(""); $("#price").val(""); $("#btw").val(""); $("#unit").val(""); } // De artikel gegevens zijn gewist. Dan ook de srtdeel_key op -1 zetten. if (bes_item_info) bes_item_info.srtdeel_key = -1; // Als het maximum aantal artikelen voor deze discipline bereikt is moet het artikel veld gedisabled worden. if (maxArtikelReached()) { $("#besitem_show").attr('disabled', true); $("#besitem_show").next('.suggestklikker').hide(); $("#srtgroep_text").html(L("lcl_bes_max_artikel_reached")); } FcltMgr.resized(window); } if (bes_item_info.num_prop>0) { // flexkenmerken vragen var prs_key = document.u2.person.value; var s = "../bes/bes_edit_item_kenmerk.asp?srtdeel_key=" + bes_item_info.srtdeel_key + "&urole=" + urole + "&srtgroup_key=" + bes_item_info.srtgroup_key + "&dis_key=" + dis_key + "&prs_key=" + prs_key; FcltMgr.openModalDetail(s, L("lcl_bes_article_details"), { callback: function (data) { continueAdd(data.objReturn)}} ); } else continueAdd(); } function openArtDetails(detailurl) { FcltMgr.windowopen(detailurl); // Unsafe: // FcltMgr.windowopen(detailurl, 'ArtDetInfo', // "width=800, height=600, directories=no,location=no,menubar=no,title='ArtDetInfo'," // + "resizable=yes,status=no,titlebar=yes,toolbar=no,scrollbars=yes"); } // Verwerk het resultaat van fetchArtikelInfo window.stock_info = {}; // forceer globale scope function fetchArtikelInfoResult( json, cell) { if (json) { window.stock_info = json; var innerTxt = "" if (json.stock) innerTxt += json.stock; if (json.details_url) { var myButton = ""; innerTxt += (json.details_url != "null"?" " + myButton:"") } $(cell).html(innerTxt); } else { $(cell).html('--'); } } // Haal (asynchroon) leverancier informatie van een artikel op. function fetchArtikelInfo(cell, srtdeel_key, id_key) { var s = "DynArtikelInfo.asp?srtdeel_key=" + srtdeel_key; $.getJSON(s, function (json) { fetchArtikelInfoResult( json, cell); } ); } var checkXhrObj = {}; function checkXhr(srtdeel_key, bes_key) { return !!(checkXhrObj[bes_key] && checkXhrObj[bes_key][srtdeel_key]); } var new_item_key = 0; // editable: ik mag nog regels toevoegen en verwijderen, verhogen en verlagen // levert een verwijzing naar de aantal_cell op. function CreateRow(bes_item_info, aantal, received, editable, objFlex, urole) { var is_new_item = false; var table = $("#sel_items>tbody")[0]; // insert data rows var tr = table.insertRow(-1); if (bes_item_info.isFreeArticle) { tr.title = L("lcl_bes_free_artgroep"); } else { tr.title = bes_item_info.opmerking; } if (!bes_item_info.item_key || String(bes_item_info.item_key).match(/^new/)) { is_new_item = true; new_item_key ++; // alstie vooralsnog maar uniek is. // Maak een kloon van bes_item_info omdat we het (compleet) gaan opslaan in de // JScript slaat alleen een referentie naar het object op en elke regel zou anders // indirect naar dezelfde key terugwijzen var binfo = {}; for (var ii in bes_item_info) // toevallig allemaal atomair dus geen deepclone nodig { binfo[ii] = bes_item_info[ii]; } bes_item_info = binfo; bes_item_info.item_key = "new" + new_item_key; } if (!bes_item_info.isFreeArticle) { tr.setAttribute("disc_key", bes_item_info.disc_key); tr.setAttribute("srtdeel_key", bes_item_info.srtdeel_key); tr.setAttribute("srtgroup_key", bes_item_info.srtgroup_key); tr.setAttribute("new_id", bes_item_info.item_key); tr.setAttribute("item_key", (is_new_item ? -1 : bes_item_info.item_key)); tr.setAttribute("urole", (is_new_item ? urole : bes_item_info.urole)); } tr.bes_item_info = bes_item_info; if (editable) { // Als er op de regel geklikt wordt en als er text wordt geselecteerd (is niet hetzelfde) dan in beide gevallen de gegevens van het artikel ophalen en tonen. $(tr).on("click select", function () { if (!checkXhr(this.bes_item_info.srtdeel_key, this.bes_item_info.bestelling_key) && !maxArtikelReached()) { load_item_info(this.bes_item_info.srtdeel_key, urole, 0, this.bes_item_info.bestelling_key ); } }); } tr.orgAmount = tr.amount = aantal; tr.flexvals = []; var id_key = bes_item_info.srtdeel_key + "_" + bes_item_info.item_key; // Create drop + info button cell = tr.insertCell(-1); cell.align = "center"; // De regels waarvan aantallen zijn geleverd moeten zeker blijven bestaan. Deze zijn al deel van deze bestelaanvraag $(cell).html( ( editable && !bes_item_info.received ? "" + I("fa-trash-alt fa-lg") + "
" : "" ) + ( editable && !is_new_item && objFlex[0].length && bes_item_info.auth.canWriteBESBOF==1 // minimaal 1 kenmerk aanwezig en BESBOF-rechten op catalogus ? "" + I("fa-fclt-edit") + "
" : "" ) + " " ); if (bes_item_info.isFreeArticle) { cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; } var new_price = aantal * bes_item_info.price; if (window.fotomode == 1) { // Create foto cell = tr.insertCell(-1); cell.vAlign = 'top'; cell.className = 'bessrtdeelfoto'; if (bes_item_info.srtdeel_image) $(cell).html(("" + cell.className + "").format(bes_item_info.srtdeel_image)); } // Create srtdeel cell = tr.insertCell(-1); cell.vAlign = 'top'; $(cell).text(bes_item_info.srtdeel_nr); cell = tr.insertCell(-1); $(cell).text(bes_item_info.srtdeel_omschrijving) if (bes_item_info.srtdeel_details_loc) { $(cell).wrapInner(""); } $(cell).append(""); if (objFlex && objFlex[0]!='') { var flexkeys = []; var flexdeels = []; var flexitems = []; var flexvals = []; var cell_arr = []; for (i=0; i").text(cell_arr[spanIndex])).append("
"); } $("#besitemflex").append(newDiv); cell.appendChild(newDiv); cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; } else { cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; cell.innerHTML += ""; } cell.innerHTML += "
"+ ""; // Create order unit field cell = tr.insertCell(-1); cell.vAlign = 'top'; cell.innerHTML = "" + bes_item_info.eenheid + ""; if (!hide_cost) { // Create Price field cell = tr.insertCell(-1); cell.innerHTML = "" + currency_pref + num2currEditable(bes_item_info.price) + ""; cell.vAlign = 'top'; cell.align = 'right'; // Create BTW field cell = tr.insertCell(-1); cell.innerHTML = "" + bes_item_info.btw + ""; cell.vAlign = 'top'; cell.align = 'right'; } // Create amount field cell = tr.insertCell(-1); var aantaltxt = float2floatEditable(aantal) || ""; if (window.is_correctie === false && aantal < 0) // === false want in show mode is 'window.is_correctie' undefined aantaltxt = "" cell.innerHTML = "" + ((editable) // Als status is 4 dan worden alleen de flexkenmerken opgeslagen NFIT#13069 ? ("") : aantaltxt); cell.innerHTML += "" + ""; cell.id = 'td' + id_key; cell.align = 'right'; cell.vAlign = 'top'; if (received >= 0) { // Create received field cell = tr.insertCell(-1); cell.innerHTML = (received > 0? float2floatEditable(received) : ""); cell.align = 'right'; cell.vAlign = 'top'; } // Nu kan de staffel zichtbaar gemaakt worden in edit mode. if (bes_item_info.staffelhtml) { $("#div" + id_key).html(bes_item_info.staffelhtml); if (editable) { $("#div" + id_key).show(); $("#img_staffelinfo" + id_key).show(); } } if (!hide_cost) { // Create price field cell = tr.insertCell(-1); cell.id = "totprice"; // Elke regel heeft zijn eigen cell met id=totprice $(cell).html(currency_pref + num2currEditable(bes_item_info.price*aantal)); cell.align = 'right'; cell.vAlign = 'top'; if ( !show_price) cell.style.display = "none"; } return $("#amount" + id_key)[0]; } // Annuleer een item(regel) function cancel_item(een_cell) { FcltMgr.confirm(L("lcl_bes_cancelItem"), function() { var maxreached = maxArtikelReached(); var tr = $(een_cell).closest("tr")[0]; var index = tr.rowIndex; var table = $("#sel_items")[0]; table.deleteRow(index); // Artikel veld nu zeker weer wijzigbaar. $("#besitem_show").attr('disabled', false); $("#besitem_show").next('.suggestklikker').show(); if (maxreached) { // De tekst lcl_bes_max_artikel_reached weer verwijderen $("#srtgroep_text").html(""); } // Indien singlegroep is gezet kunnen binnen een catalogus uitsluitend artikelen uit dezelfde groep worden besteld. Alle artikelen in de bestellijst moeten dan uit dezelfde groep komen. // Indien er geen bestelregels aanwezig zijn mag de artikelgroep worden gewijzigd. if ($("#singlegroep").val() == 1) { // Indien readOnly (initieel) is gezet blijft de input box ook readonly. sgSrtgroep is dan ook niet gedefinieerd. $("#srtgroep_show")[0].style.display = "block" doet dan toch niets. if (getAantalArtikelen() == 0 && !$("#srtgroep_show")[0].readOnly) { $("#srtgroep_ro")[0].style.display = "none"; $("#srtgroep_show")[0].style.display = "block"; } } if (getAantalArtikelen() == 0) $("#lev_key_show").prop('disabled', false); // Je mag eventueel weer leverancier kiezen StaffelKortingResult(); }); } function edit_kenmerk_item(een_cell) { var $tr = $(een_cell).closest("tr"); var prs_key = document.u2.person.value; var srtdeel_key = $tr.attr("srtdeel_key"); var item_id = $tr.attr("new_id"); v_url = "../bes/bes_edit_item_kenmerk.asp" + "?urole=" + $tr.attr("urole") + "&srtdeel_key=" + $tr.attr("srtdeel_key") + "&srtgroup_key=" + $tr.attr("srtgroup_key") + "&dis_key=" + $tr.attr("disc_key") + "&prs_key=" + prs_key + "&item_key=" + $tr.attr("item_key") + "&km_key=" + $("#flexkeys"+srtdeel_key+"_"+item_id).val() + "&km_val=" + $("#flexvals"+srtdeel_key+"_"+item_id).val(); FcltMgr.openModalDetail(v_url, L("lcl_kenmerk_frame"), {callback: FcltMgr.reload}); } function checkInput() { var filled_lines = 0; var blank_lines = 0; $("#sel_items>tbody>tr").not(".bessrtgroepname").each( function () { if (this.amount != 0) filled_lines++; else blank_lines++; }); if (!filled_lines) { FcltMgr.alert(L("lcl_bes_noItems")); // Er zijn geen volledig ingevulde factuurregels. return false; } // Form srtdeel_keys and amount_string // and form flexkey_string and flexval_string of items var srtdeel_keys = []; var amount_string = []; var flexkey_string =[]; var flexval_string = []; var flexdeel_string = []; var flexitem_string = []; var item_keys = []; var id_key = ""; var p = 0; $("#sel_items>tbody>tr").not(".bessrtgroepname").each( function () { id_key = this.bes_item_info.srtdeel_key + "_" + this.bes_item_info.item_key; if ($("#flexkeys" + id_key).val() != -1) { flexkey_string.push($("#flexkeys" + id_key).val()); flexval_string.push(this.flexvals); flexdeel_string.push($("#flexdeels" + id_key).val()); flexitem_string.push($("#flexitems" + id_key).val()); } srtdeel_keys.push(this.bes_item_info.srtdeel_key); amount_string.push(this.amount); item_keys.push(this.bes_item_info.item_key); p++; }); if (!p) { FcltMgr.alert(L("lcl_bes_noItems")); return false; } $("#srtdeel_keys").val(srtdeel_keys.join(",")); $("#amount_string").val(amount_string.join(",")); $("#item_keys").val(item_keys.join(",")); $("#flexkey_string").val(flexkey_string.join(",")); $("#flexval_string").val(flexval_string.join(",")); $("#flexdeel_string").val(flexdeel_string.join(",")); $("#flexitem_string").val(flexitem_string.join(",")); return true; } function makeorder_callback(json) { iface.button.enable("btn_bes_submit"); if (json.success) { FcltMgr.closeDetail(window, json); } } async function MakeOrder (newOrder) { $(document.activeElement).trigger("blur"); // trigger laatste onChanges if (typeof window.blurEvent === "object" && window.blurEvent instanceof Promise) { await window.blurEvent; } // Standaard checks op verplichte velden, datum formaat, numeriek en float formaat, currency formaat. if (!await validateForm("u2", { checkNot: jqFreeFields })) { return false; } // Formulier specifieke checks if (!checkInput()) return false; var cal = $('#calendar'); var autoConf = true; if (cal.length) { levDate = new Date(parseInt(cal.val(), 10)); autoConf = !cal_isVrijeDag(levDate); } FcltMgr.confirm( L("lcl_bes_date_holiday") , { autoconfirm: autoConf , fncancel: function() { iface.button.enable("btn_bes_submit") } } , function() { // Alleen als op de vrachtwagen geklikt is, en de setting aan staat // om bevestiging van de bestelopdracht vragen. var autoConfirm = !(confirm_order_before_submit && (newOrder == 0)); FcltMgr.confirm( L("lcl_bes_confirm_order") , { autoconfirm: autoConfirm , fncancel: function() { iface.button.enable("btn_bes_submit") } } , function() { $.post( $("form[name=u2]")[0].action , $("[name=u2]").serialize() , FcltCallbackAndThenAlways(makeorder_callback) , "json" ); }); }); return true; // disabled button ook } // UWVA#13497 Ooit bedacht om klachten over leveranciers in DAMO te registreren // Nooit in productie genomen? function Communication() { bes_key = document.getElementById("RFO_key").value; $.post("bes_levopm.asp", { bes_key: bes_key }, FcltCallback, "json"); } function showStaffels(pid_key) { if (document.getElementById('div' + pid_key).style.display == "block") document.getElementById('div' + pid_key).style.display = "none"; else if (document.getElementById('div' + pid_key).style.display == "none") document.getElementById('div' + pid_key).style.display = "block"; } function getTrText(td1, td2, td3, total_text, total_value, tdid) { var trText = '' + '' + '' + '' + '' + td2 + '' + '' + td3 + '' + '' + total_text + '' + ''; return trText; } function addColor(pbedrag) { if (pbedrag > 0) return '' + currency_pref + num2curr(pbedrag) + '' else if (pbedrag < 0) return '' + currency_pref + num2curr(pbedrag) + '' else return pbedrag } function showStaffelKortingResult( json) { if (json) { var bes_kosten = json.bes_kosten||0; var bes_limiet = json.bes_limiet||0; var prs_bedrijf_key = json.prs_bedrijf_key; var iakorting = json.iakorting||0; var totaalbedrag = json.totaalbedrag||0; var sgnaamstring = json.sgnaamstring || []; var sgkeystring = json.sgkeystring || []; var sgkortingstring = json.sgkortingstring || []; var sgaantalstring = json.sgaantalstring || []; var sgeenheidstring = json.sgeenheidstring || []; // Als sgnaamstring dan zijn er groepsstaffels if (sgnaamstring && (sgkeystring.length != sgnaamstring.length || sgkeystring.length != sgkortingstring.length || sgkeystring.length != sgaantalstring.length)) { // FcltMgr.alert(L("lcl_internal_error") + ": showStaffelKortingResult.asp, aantal staffelgroepen komt niet overeen met het aantal kortingen!"); } var tabeltext = ""; var subtotaal = 0; if (show_price) { tabeltext = ''; for (var i = 0; i < sgnaamstring.length; i++) { if (sgkortingstring[i] != 0) { tabeltext += getTrText((sgkortingstring[i] * -1 < 0? L("lcl_bes_st_discount_gp") : L("lcl_bes_st_excharge_gp")) + ": " + sgnaamstring[i], sgaantalstring[i] + " x " + sgeenheidstring[i], addColor(sgkortingstring[i] * -1), "", sgkortingstring[i], "gs" + sgkeystring[i]); subtotaal += sgkortingstring[i] * -1; } } if (iakorting) { tabeltext += getTrText(((iakorting * -1) < 0? L("lcl_bes_st_discount_ind") : L("lcl_bes_st_excharge_ind")), "", addColor(iakorting * -1), "", iakorting, "ia"); subtotaal += (iakorting * -1); } if (subtotaal != 0) { tabeltext += getTrText(L("lcl_bes_st_discount_tot"), "", "", addColor(currency_pref + num2curr(subtotaal)), num2curr(subtotaal), "subtotaal"); } if (bes_kosten) { tabeltext += getTrText(L("lcl_bes_st_tpcosts_under") + bes_limiet, "", "", addColor(currency_pref + num2curr(bes_kosten)), num2curr(bes_kosten), "bk"); } tabeltext += getTrText(L("lcl_bes_total_cost"), "", "", currency_pref + num2curr(totaalbedrag), num2curr(totaalbedrag), "total"); tabeltext += "
"; } $("#total_list").html(tabeltext); FcltMgr.resized(); } else { var tabeltext = ""; if (show_price) { tabeltext = ''; tabeltext += getTrText(L("lcl_bes_total_cost") + ' ' + currency_pref, "", "", 0, 0, "total"); tabeltext += "
"; $("#total_list").html(tabeltext); } } FcltMgr.resized(window, { noMasonry: true }); } function StaffelItem(item_key, aantal) { this.item_key = item_key; this.aantal = aantal; } async function onBlurAmount(aantal_cell) { const data = await getSupplyData(aantal_cell); return new Promise((resolve) => { checkAmount(aantal_cell, data); StaffelKortingResult(); resolve(true); }); } function getSupplyData(aantal_cell) { return new Promise((resolve, reject) => { if (window.bestelmode == 2) { // Autobestellijst var tr = $(aantal_cell).closest("tr")[0]; var data = { srtdeel_key: tr.bes_item_info.srtdeel_key , urole: tr.getAttribute("urole") }; $.when($.get( "get_bes_info_ajax.asp?req_info=voorraad_artikel", data, null, "json")).then((rdata) => { var vdata = { voorraad: rdata.voorraad_intern , maxbestel: rdata.maxbestel }; resolve(vdata); }).fail((response) => { reject("Failed $.get from 'get_bes_info_ajax.asp' => " + response.statusText + " (" + response.status + ")"); }); } else { var vdata = { voorraad: parseFloat(window.stock_info.stock) || 0 , maxbestel: parseInt(window.stock_info.maxbestel, 10) || 0 }; resolve(vdata); } }); } // Toont de totaal regel (al dan niet met staffelkorting) function StaffelKortingResult() { if (hide_cost) return; var staffelItemArray = new Array(); var json = null; // Bij isFreeArticle 'resultaat' van bes_gettotals.asp var anyFree = false; // Dan moeten we het helemaal clientside oplossen $("#sel_items>tbody>tr").not(".bessrtgroepname").each( function () { json = json || { totaalbedrag: 0 }; // voor FreeArtikel json.totaalbedrag += this.amount * this.bes_item_info.price; anyFree = anyFree || this.bes_item_info.isFreeArticle // die gaan niet via bes_gettotals.asp dus zelf totaal bepalen var srtdeel_key = this.bes_item_info.srtdeel_key; if (this.amount) { if (staffelItemArray[srtdeel_key]) // aantallen van een item bij elkaar optellen staffelItemArray[srtdeel_key].aantal += this.amount; else staffelItemArray[srtdeel_key] = new StaffelItem(srtdeel_key, this.amount, 10) } } ); var itemstring = ""; var itemaantalstring = ""; var first = true; for (var j in staffelItemArray) { if (staffelItemArray[j] && staffelItemArray[j].item_key > 0) { itemstring += (!first? "," : "" ) + staffelItemArray[j].item_key; itemaantalstring += (!first? "," : "" ) + staffelItemArray[j].aantal; first = false; } } if (hasAnyStaffels && !anyFree && itemstring != "") { // Haal (asynchroon) korting informatie op van de artikelen var s = "bes_gettotals.asp?itemstring=" + itemstring + "&itemaantalstring=" + itemaantalstring; $.getJSON(s, showStaffelKortingResult ); } else showStaffelKortingResult( json ) return; } function checkAmount(aantal_cell, voorraad_data) { var tr = $(aantal_cell).closest("tr")[0]; var aantal = (aantal_cell.value.indexOf(",") != -1 ? aantal_cell.value.replace(",", ".") : aantal_cell.value ); var amount = parseFloat(aantal); var id_key = aantal_cell.id.substring(6); var valid = true; var error = ""; if (aantal_cell.value == '') { if (window.bestelmode == 2) // Bij autobestellijst staan we gewoon 0 of leeg toe. aantal = amount = 0; else aantal = amount = 1; } valid = !isNaN(amount) && isGoodNumber(aantal, false, false, 15, 3) && amount <= 99999; validateField(aantal_cell, valid, L("lcl_bes_invalidAmount")); if (!valid) return; if (!window.is_correctie) { var besteld = 0; for (var i = 0; i < $("input[id^='amount" + tr.bes_item_info.srtdeel_key + "']").length; i++) { besteld += parseFloat($("input[id^='amount" + tr.bes_item_info.srtdeel_key + "']")[i].value); } var voorraad = voorraad_data.voorraad; var reduced = false; var max_bestel; if (voorraad_data.maxbestel > 0) // -> Maximum bestelaantal is voorraad { // Aantal verlagen naar het aantal dat in voorraad is min het aantal dat in andere regels in bestelling is. max_bestel = voorraad - (besteld - amount); if (besteld > voorraad) { if (max_bestel < 0) max_bestel = 0; valid = false; error = L("lcl_bes_reduced_to_max").format(voorraad, max_bestel); aantal_cell.value = max_bestel; aantal = max_bestel; besteld = voorraad; amount = parseFloat(aantal); reduced = true; } } var bestelminimum = tr.bes_item_info.bestelminimum; var bestelmaximum = tr.bes_item_info.bestelmaximum; if (bestelmaximum > -1 && besteld > bestelmaximum) { aantal_cell.value = bestelmaximum - (besteld - amount); aantal = bestelmaximum - (besteld - amount); amount = parseFloat(aantal); error = (error != ""? error + "
": "") + L("lcl_bes_bestelmaximum") + bestelmaximum; reduced = true; valid = false; } if (amount < bestelminimum && amount != 0) { if (reduced || (voorraad_data.maxbestel > 0 && max_bestel < bestelminimum)) { amount = 0; // Als het aantal al is gereduceerd tot wat in voorraad is en besteld mag worden dan mag je niets meer bestellen. // Als het aantal wat in voorraad is en besteld mag worden lager is als het bestelminimum dan mag je niets meer bestellen. error = (error != ""? error + "
": "") + L("lcl_bes_stock_too_low"); } else { amount = bestelminimum; error = (error != ""? error + "
": "") + L("lcl_bes_bestelminimum") + bestelminimum; } valid = false; aantal_cell.value = amount; aantal = amount; } var veelvoud = tr.bes_item_info.veelvoud; if (!tr.bes_item_info.isFreeArticle) { if ( (pcs = xfloatMod(amount, veelvoud)) != 0) { amount = xfloatSub(xfloatAdd(amount, veelvoud), pcs); // Het kan zijn dat nu het aantal groter is als de voorraad en dat het niet mag. if (voorraad_data.maxbestel > 0 && amount > voorraad) amount = xfloatSub(amount, veelvoud); valid = false; error = (error != ""? error + "
": "") + L("lcl_bes_matchedveelvoud") + veelvoud; aantal_cell.value = amount; aantal = amount; } } validateField(aantal_cell, valid, error); // Als er items geleverd zijn, mag het aantal daar niet onder komen // Of laten we de leverancier dit dan gewoon afkeuren? if (tr.bes_item_info.received > 0) { if ((amount < tr.bes_item_info.received && tr.orgAmount >= 0) || (amount > tr.bes_item_info.received && tr.orgAmount <= 0)) { validateField(aantal_cell, false, L("lcl_bes_exceed_delivered")); return; } } } if (!valid && amount == 0) $(aantal_cell).removeClass("bad"); // Als het aantal weer op nul is gezet dan is dat ok, maar dan heb ik eventueel wel een melding. tr.amount = amount; // voor het gemak if (!show_price || hide_cost) return; var new_price = amount * tr.bes_item_info.price; // Elke regel heeft zijn eigen cell met id=totprice $("#totprice", tr).text(currency_pref + num2currEditable(new_price)); $("#price" + id_key).val(num2curr(new_price)); } // niet nodig: function xfloatMul(x, y) // niet nodig: function xfloatDiv(x, y) function xfloatMod(x, y) { // Berekenen van rest na deling met decimale getallen is onnauwkeuring vanwege de binaire notatie van het getal in een float. // Daarom wordt er hier eerst een integer van gemaakt. var c = xfloatCollect(x, y); var xy = (parseInt(c.x.t, 10) % parseInt(c.y.t, 10)) / Math.pow(10, c.max_decimals); return xy; } function xfloatAdd(x, y) { // Som van twee floats is niet altijd exact. var c = xfloatCollect(x, y); var xy = parseInt(c.x.t, 10) + parseInt(c.y.t, 10); xy = xy / Math.pow(10, c.max_decimals); return xy; } function xfloatSub(x, y) { // Verschil van twee floats is niet altijd exact. var c = xfloatCollect(x, y); var xy = parseInt(c.x.t, 10) - parseInt(c.y.t, 10); xy = xy / Math.pow(10, c.max_decimals); return xy; } function xfloatCollect(x, y) { // Gegevens van float x en y: aantal decimalen en maak er een interger van door met een veelvoud van 10 te vermenigvuldigen. var tx = x.toString().replace(".", ""); var ty = y.toString().replace(".", ""); var cnt_xDecimals = (x.toString().split(".").length == 1 ? 0 : x.toString().split(".")[1].length); var cnt_yDecimals = (y.toString().split(".").length == 1 ? 0 : y.toString().split(".")[1].length); for (i=0; i<(cnt_yDecimals - cnt_xDecimals); i++) { tx += "0"; } for (i=0; i<(cnt_xDecimals - cnt_yDecimals); i++) { ty += "0"; } c = { x: {x: x, t: tx, d: cnt_xDecimals} , y: {y: y, t: ty, d: cnt_yDecimals} , max_decimals: Math.max(cnt_xDecimals, cnt_yDecimals) } return c; }