PageSourceSearch

https://dereta.rs/templates/B2C/skins/main/js/kendoBasket1.js?12

js dereta.rs collected 2026-10-02 12:00:27 UTC 30,448 bytes, 761 lines download raw bytes

1BasketViewModel = {
2    init: function () {
3        this.showBasket();
4    },
5    dataSource: function () {
6        return {
7            type: "json",
8            transport: {
9                read: "/Services/EcommerceService.svc/GetBasketItems?B2BMode=false"
10            },
11            pageSize: 50,
12            navigatable: true,
13            schema: {
14                // parse: function (data) {
15                //     return data;
16                // },
17                data: function (data) {
18
19                    data.d.ShippingAddress[0].Countrys = data.d.Countrys;
20
21                    data.d.ShippingAddress[0].Countrys.forEach(function (c) {
22                        if (c.Uid == data.d.ShippingAddress[0].CountryUid) {
23                            c.Selected = true;
24                        }
25                        else {
26                            c.Selected = false;
27                        }
28                    })
29
30                    return [data.d];
31                },
32                model: {
33                    id: "basketItemUid",
34                    fields: {
35                        basketItemUid: { from: "uid", type: "string", editable: false },
36                        Name: { type: "string", editable: false },
37                        ItemPrice: { type: "number", editable: false },
38                        Qty: { type: "number", editable: true, validation: { required: true, min: 1 } },
39                        ItemPriceTotal: { type: "number", editable: false },
40                        Identifier: { type: "string" },
41                        VAT: { type: "string", editable: false },
42                    }
43                }
44            },
45            aggregate: [{ field: "ItemPriceTotal", aggregate: "sum" }, { field: "VAT", aggregate: "sum" }]
46        };
47    },
48
49    showGrid: function () {
50        _self = this;
51        $("#grid").kendoGrid({
52            autoBind: true,
53            dataSource: BasketViewModel.dataSource(),
54            toolbar: ["create"],
55            messages: {
56                commands: {
57                    create: "Dodaj novi proizvod",
58                }
59            },
60            editable: {
61                confirmation: "Da li ste stiguni da zelite da izbacite proizvod iz porudžbenice?"
62            },
63            remove: function (e) {
64                if (e.model.SalesType == 1) {
65                    $.get("/EcommerceService.svc/RemoveFromBasketAjax?SalesItemUid=" + e.model.basketItemUid, function (data) {
66                        customNotify({message: 'Uspešno ste izbacili proizvod iz porudžbenice', type: 'success', delay: 1500});
67                        BasketBehaivorObj.GetAndRefreshBasket($(this));
68                    });
69                } else {
70                    customNotify({message: 'Ovaj proizvod nije moguće izbaciti iz porudžbenice.'});
71                }
72
73                $('#grid').data('kendoGrid').dataSource.read();
74
75            },
76            save: function (e) {
77
78            },
79            crete: function (e) { },
80            editable: true,
81            dataBound: function () {
82                var rows = this.items();
83                $(rows).each(function () {
84                    var index = $(this).index() + 1;
85                    var rowLabel = $(this).find(".row-number");
86                    $(rowLabel).html(index);
87                });
88            },
89            columns: [
90                {
91                    title: "#",
92                    template: "<span class='row-number'></span>",
93                    width: 35
94                }, {
95                    field: "Identifier",
96                    title: "Sifra Proizvoda",
97                    attributes: { style: "text-align:center" },
98                    width: 100,
99                    filterable: false
100                    // }, {
101                    //     command: [
102                    //         { text: " ", click: this.showDetail
102s, className: "k-icon k-i-preview k-small-button fa fa-eye" }
103                    //     ], title: " ", width: "50px", attributes: { style: "text-align:center;" }
104                }, {
105                    field: "Name",
106                    title: "Naziv Proizvoda",
107                    attributes: { style: "text-align:left" },
108                    filterable: false
109                }, {
110                    field: "Qty",
111                    title: "Kolicina",
112                    template: '<div id=#=basketItemUid# style="width: calc(100% - 10px);text-align:center;outline: none;border:1px solid darkgrey;margin:0 auto;padding:3px">#= Qty #</div>',
113                    attributes: { style: "text-align:center;" },
114                    width: 75,
115                    filterable: false
116                }, {
117                    field: "ItemPrice",
118                    title: "Cena",
119                    template: '#= kendo.toString(ItemPrice/1.2, "n2") # EUR',
120                    attributes: { style: "text-align:right;" },
121                    width: 120,
122                    filterable: false
123                }, {
124                    title: "Ukupno bez PDV",
125                    template: '#= kendo.toString(ItemPriceTotal/1.2, "n2") # EUR',
126                    attributes: { style: "text-align:right;" },
127
128                    width: 120,
129                    filterable: false
130                }, {
131                    title: "PDV",
132                    template: '#= kendo.toString((ItemPrice - ItemPrice/1.2), "n2") # EUR',
133                    attributes: { style: "text-align:right;" },
134                    filterable: false,
135                    width: 160
136                }, {
137                    field: "ItemPriceTotal",
138                    title: "Ukupna cena sa PDV",
139                    template: '#= kendo.toString(ItemPriceTotal, "n2") # EUR',
140                    attributes: { style: "text-align:right;" },
141                    filterable: false,
142                    width: 175,
143                }, { command: { name: "destroy", text: "" }, width: 75 }
144            ], editable: true
145        });
146
147    },
148
149    showBasket: function () {
150        var _self = this;
151        $("#basketContainer").kendoListView({
152            autoBind: true,
153            dataSource: BasketViewModel.dataSource(),
154            template: kendo.template($("#basketTemplate").html()),
155            dataBinding: function (event) {
156                if ($("#basketContainer").data("kendoListView").dataSource.data()[0].BasketItems.length <= 0) {
157                    event.preventDefault();
158                    handleEmptyBasket();
159                }
160            },
161            dataBound: function () {
162
163                const freeShippingTreshold = $("#basketContainer").data("kendoListView").dataSource.data()[0]?.FreeShipping;
164
165                checkForLogin();
166                calculateFreeShipping(freeShippingTreshold);
167                checkForShippingMap();
168
169                $("[data-remove-from-basket]").on('click', function () {
170                    _self.removeFromBasket($(this).attr("data-sales-item-uid"));
171                });
172
173                document.getElementById('terms_agree').addEventListener('change', function () {
174                    if (this.checked) {
175                        $(this).closest('.buttons-1').addClass('checked');
176                    } else {
177                        $(this).closest('.buttons-1').removeClass('checked');
178                    }
179                });
180
181                switchPrav();
182
183                $('#pravnoLice').on('change', function() {
184                    // $('#txtName').val('');
185                    switchPrav();
186                })
187                $('#fizickoLice').on('change', function() {
188                    // $('#txtCompanyName').val('');
189                    // $('#txtPIB').val('');
190                    switchPrav();
191                });
192
193                // Hide the loader when everything is finished:
194                $('.custom-loader').fadeOut();
195                $('.basket-order-loader').fadeOut();
196                $('#ButtonCheck').removeClass('loading');
197
198                analyticsBeginCheckout();
199            
200            }
201            // template: kendo.template(window.innerWidth <= 991 ? $("#listResultTemplate").html() : $("#listResultTemplateD").html())
202        });
203    },
204
205    showList: function () {
206        var _self = this;
207        var Grid = window.innerWidth <= 991 ? "grid" : "gridD";
208        $("#" + Grid).kendoListView({
209            autoBind: true,
210            dataSource: BasketViewModel.dataSource(),
211            dataBound: function () {
212
213                $("[data-remove-from-basket]").on('click', function () {
214                    _self.removeFromBasket($(this).attr("data-sales-item-uid"));
215                });
216
217            },
218            template: kendo.template(window.innerWidth <= 991 ? $("#listResultTemplate").html() : $("#listResultTemplateD").html())
219        });
220    },
221
222    removeFromBasket: function (SalesItemUid) {
223        if (confirm("Da li želite da obrišete proizvod iz porudžbenice?")) {
224            sessionStorage.removeItem('BasketUI');
225            $.get("/EcommerceService.svc/RemoveFromBasketAjax?SalesItemUid=" + SalesItemUid, function (data) {
226                customNotify({message: 'Uspešno ste izbacili proizvod iz porudžbenice', type: 'success', delay: 1500});
227
228                // var Grid = window.innerWidth <= 991 ? "grid" : "gridD";
229                $("#basketContainer").data("kendoListView").dataSource.read();
230                BasketBehaivorObj.GetAndRefreshBasket($(this));
231            });
232        }
233    },
234
235    changeQty: function (container, SalesItemUid, Qty, prevQty) {
236        // console.log({container, SalesItemUid, Qty, prevQty});
237
238        const parsedQty = parseInt(Qty);
239        const parsedPrevQty = parseInt(prevQty);
240
241        if (parsedQty > 0) {
242            
243            $('.basket-order-loader').show();
244            $('input[name="quantity"]').attr('disabled', true);
245            $('#ButtonCheck').addClass('loading');
246
247            $.get("/EcommerceService.svc/BasketChangeItemCount?ItemUid=" + SalesItemUid + "&Count=" + Qty, function (data) {
248
249                const opRes = data.d?.OperationResult;
250                const errMes = data.d?.ErrorMessage;
251
252                const messages = {
253                    2: `Proizvoda ${errMes} nema u zahtevanoj količini, probajte sa manjom količinom.`,
254                    5: `Uneta količina ne odgovara zahtevanom transportnom pakovanju. Transportno pakovanje je: ${parseFloat(errMes)}.`,
255                    6: `Proizvod sadrži varijacije.`,
256                    7: `Uneta količina nije validna.`,
257                    8: `Uneta količina je manja od zahtevane minimalne količine. ${errMes ? '(' + parseFloat(errMes) + ')' : ''}`,
258                    default: `Dodavanje u korpu nije uspelo, pokušajte ponovo.`,
259                };
260
261                if (opRes === 0) {
262                    customNotify({
263                        message: `Za proizvod ${errMes}, uspešno ste izmenili količinu.`,
264                        type: 'success',
265                        delay: 2000,
266                    })
267
268                    $("#basketContainer").data("kendoListView").dataSource.read();
269                    sessionStorage.removeItem('BasketUI');
270                    BasketBehaivorObj.GetAndRefreshBasket($(this));
271
272                    return;
273                }
274
275                const message = messages[opRes] || messages.default;
276                customNotify({ message, type: opRes in messages ? 'notice' : 'error' });
277                $(container).val(parsedPrevQty);
278                $('.basket-order-loader').fadeOut();
279                $('input[name="quantity"]').attr('disabled', false);
280                $('#ButtonCheck').removeClass('loading');
281
282            });
283
284        } else {
285            customNotify({message: 'Uneli ste nedozvoljenu količinu.', type: 'error'});
286            $(container).val(parsedPrevQty);
287        }
288
289    },
290
291    pravChecked: false,
292    fizChecked: true,
293
294}
295
296
297
298
299
300$(function () {
301
302    BasketViewModel.init();
303
304    $("[data-require='true']").each(function (index) {
305        if (!$(this).val()) {
306            console.log($(this).attr('id') + ": " + $(this).val());
307            $(this).addClass("require-data");
308        }
309    });
310
311    $("[data-require='true']").on('change', function () {
312        console.log("1");
313        $(this).removeClass("require-data");
314    });
315
316})
317
318
319function ChangeShippingAddress(selectObject) {
320    var value = selectObject.value;
321    $.get("/Services/EcommerceService.svc/ChangeShippingAddress?ClientDirrectionUid=" + value, function (data) {
322        // console.log(data);
323        if (data.d == true) {
324            customNotify({message: 'Adresa za isporuku uspešno promenjena', type: 'success'});
325        } else {
326            customNotify({message: 'Nije uspela promena adrese za isporuku'});
327        }
328        $("#basketContainer").data("kendoListView").dataSource.read();
329    });
330}
331
332function ChangePaymentMethod(selectObject) {
333    var value = selectObject.value;
334    $.get("/Services/EcommerceService.svc/ChangePaymentMethod?PaymentMethodUid=" + value, function (data) {
335        // console.log(data);
336        if (data.d == true) {
337            customNotify({message: 'Način plaćanja uspešno promenjen', type: 'success'});
338        } else {
339            customNotify({message: 'Nije uspela promena načina plaćanja'});
340        }
341    });
342
343}
344
345function ChangeShippingMethod(selectObject) {
346    var value = selectObject.value;
347    $.get("/Services/EcommerceService.svc/ChangeShippingMethod?ShippingMethodPriceUid=" + value, function (data) {
348        if (data.d == true) {
349            customNotify({message: 'Način isporuke uspešno promenjen', type: 'success'});
350        } else {
351            customNotify({message: 'Nije uspela promena načina isporuke'});
352        }
353        $("#basketContainer").data("kendoListView").dataSource.read();
354    });
355
356}
357
358function UpdateShippingAddress(container) {
359    var a = $(container);
360    var Field = a.attr("data-field");
361
362    if (Field && a.val()) {
363        $.get("/Services/EcommerceService.svc/SaveShippingAddress?Key=" + Field + "&Value=" + a.val(), function (data) {
364            if (Field == "CountryUid") {
365                $("#basketContainer").data("kendoListView").dataSource.read();
366            }
367        });
368    }
369}
370
371function switchPrav() {
372    if ($('#pravnoLice').prop('checked')) {
373        BasketViewModel.pravChecked = true;
374        BasketViewModel.fizChecked = false;
375        $('.fizicko-lice').hide();
376        $('.pravno-lice').show();
377    } else if ($('#fizickoLice').prop('checked')) {
378        BasketViewModel.pravChecked = false;
379        BasketViewModel.fizChecked = true;
380        $('.fizicko-lice').show();
381        $('.pravno-lice').hide();
382    }
383    $("[data-require='true']").removeClass("require-data");
384}
385
386function ChangeNote(selectObject) {
387    var value = $(selectObject).val();
388    $.get("/Services/EcommerceService.svc/ChangeBasketNote?Note=" + value, function (data) {
389        // console.log(data);
390        if (data.d == true) {
391            customNotify({message: 'Napomena uspešno promenjena', type: 'success'});
392        } else {
393            customNotify({message: 'Nije uspela promena napomene'});
394        }
395    });
396}
397
398function AddPromoCode() {
399    var value = $("#txtPromoCode").val();
400    $.get("/Services/EcommerceService.svc/AddPromoCode?PromoCode=" + value, function (data) {
401        // console.log(data.d);
402        if (data.d && data.d.State == 1) {
403            alert(data.d.Message);
404        }
405        $("#basketContainer").data("kendoListView").dataSource.read();
406    });
407
408}
409
410function RemovePromoCode() {
411    $.get("/Services/EcommerceService.svc/AddPromoCode?PromoCode=", function (data) {
412        // console.log(data.d);
413        $("#basketContainer").data("kendoListView").dataSource.read();
414        sessionStorage.removeItem('BasketUI');
415        BasketBehaivorObj.GetAndRefreshBasket($(this));
416    });
417}
418
419var LocalItems = GetDataFromLocalStorage("LocalBulkItems");
420
421function LoadLocalItems(Callback) {
422    $.ajax({
423        url: "/Services/EcommerceService.svc/ItemsForLocalDB?query=",
424        success: function (result) {
425            SaveDataToLocalStorage("LocalBulkItems", result);
426            Callback(result);
427        }
428    });
429}
430
431function findLocalItem(container) {
432
433    if (LocalItems == null || LocalItems == []) {
434        console.log("Loading items from server");
435        //get sales items from server
436        LoadLocalItems(function (result) {
437            _self.LocalItems = result;
438        })
439    }
440
441    // var _self = this;
442    $(".search-container").remove();
443    var PartexternalID = container.val();
444
445    // sklanjanje X za čišćenje
446    if (PartexternalID.length > 0) {
447        container.next('.clearinput').show();
448    } else {
449        container.next('.clearinput').hide();
450    }
451
452    if (PartexternalID.length > 2) {
453        //IDB.getAll("items", function (a) {
454        var items = $.map(LocalItems, function (val, key) {
455            if (val.Identifier.toLowerCase().indexOf(PartexternalID.toLowerCase()) != -1 || val.Name.toLowerCase().indexOf(PartexternalID.toLowerCase()) != -1) return val;
456        })
457
458        if (items.length > 0) {
459            var searchContainer = $("<div class='search-container'></div>");
460
461            // _self.clearStatus(container.closest('.fixed-row-input'));
462
463
464            // za filtriranje šifri koje su već unete? 
465            // TODO: Refator user map()
466            let existingInputs = [];
467            $("input[name='id[]']:not(:focus)").each(function () { existingInputs.push($(this).val()) });
468
469            let mapIdents = items.map(item => item.identifier);
470
471            existingInputs.forEach(exs => {
472                if (exs.length > 2 && mapIdents.includes(exs)) {
473                    items = items.filter(item => !item.identifier.includes(exs));
474                }
475            });
476
477            if (items.length > 50) {
478                items = items.splice(0, 50);
479            }
480            items.forEach(function (item) {
481                searchContainer.append(`
482                    <div class='single-item' data-idf="${item.Identifier}" data-pname="${item.Name}" onclick="BulkAddToBasket(this)">
483                        <div class="entry">
484                            <div class="name">${item.Name}</div>
485                            <div class="attributes">${item.Identifier}</div>
486                        </div>
487                    </div>
488                `);
489            })
490
491            if (items.length > 0) { container.after(searchContainer); }
492
493        } else {
494            // Proizvod nije nađen / šifra nije dobra:
495            container.css('border', '1px solid var(--red)');
496            container.closest('.fixed-row-input').find('.bulk-status').html('<i class="feather icon-x-circle text-danger"></i>').attr('title', 'Uneta šifra nije nađena');
497            container.closest('.fixed-row-input').find('input[name="qty[]"]').val('').attr('disabled', 'disabled');
498        }
499    } else {
500        // ? uneto manje od 3 karaktera, dropdown se ne pokazuje
501        container.closest('.fixed-row-input').find('input[name="qty[]"]').val('').attr('disabled', 'disabled');
502        // _self.clearStatus(container.closest('.fixed-row-input'));
503    }
504
505}
506
507function BulkAddToBasket(container) {
508    var id = $(container).attr("data-idf");
509    var qty = 1;
510    $(".search-container").remove();
511
512    $.get(`/EcommerceService.svc/AddToBasketByIdentifier?Identifier=${id}&Qty=${qty}`, function (data) {
513        $("#basketContainer").data("kendoListView").dataSource.read();
514
515    }).fail(function (err) {
516        alert("neuspesno");
517    });
518}
519
520function FinishOrder() {
521    $('#ButtonCheck').addClass('loading');
522
523    $.ajax({
524        url: '/Services/EcommerceService.svc/FinishOrderB2C',
525        method: 'GET',
526        success: function (data) {
527        // console.log(data);
528
529        const opRes = data.d?.OperationResult;
530        const message = data.d?.Message || '';
531        const parsedMessage = message ? JSON.parse(message) : null;
532        // console.log({opRes, parsedMessage});
533
534        if (opRes == 0) {
535            // Ok
536            location.href = "/zavrsena-kupovina.aspx?uid=" + data.d.DocumentUid;
537        } else if (opRes == 3) {
538            // ErrorSendMail
539            customNotify({message: 'Porudžbenica je završena, ali je došlo do greške u slanju e-maila.'});
540            location.href = '/';
541        } else if (opRes == 4) {
542            // InvalidTransportPackage
543            customNotify({message: 'Određeni artikli imaju količine koje ne odgovaraju transpotnom pakovanju, proverite unete količine.'});
544            
545            parsedMessage.forEach(item => {
546                $(`.single-product[data-uid=${item.Uid}] input`).addClass('border-danger').after(`<small class="error-msg">Transportno pakovanje: ${item.Package}</small>`);
547            });
548            
549        } else if (opRes == 5) {
550            // InvalidMinimalOrder
551            customNotify({message: 'Određeni artikli imaju količine koje su manje od minimalne, proverite unete količine.'});
552
553            parsedMessage.forEach(item => {
554                $(`.single-product[data-uid=${item.Uid}] input`).addClass('border-danger').after(`<small class="error-msg">Minimalna količina: ${item.MinimalOrderQty}</small>`);
555            });
556
557        } else {
558            customNotify({message: 'Završavanje porudžbenice nije uspelo, proverite tačnost unetih podataka i pokušajte ponovo.', type: 'error'});
559        }
560        },
561        error: function (err) {
562            console.log(err);
563            customNotify({message: 'Završavanje porudžbenice nije uspelo, molimo pokušajte ponovo.', type: 'error'});
564        },
565        complete: function () {
566            $('#ButtonCheck').removeClass('loading');
567            if (recaptchaBasketWidgetId !== undefined) {
568                grecaptcha.reset(recaptchaBasketWidgetId);
569            }
570        }
571    });
572}
573
574function isEmail(email) {
575    var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
576    return regex.test(email);
577}
578
579function onSubmit(token) {
580    $('#ButtonCheck').addClass('loading');
581    $.ajax({
582        url: '/Services/EcommerceService.svc/VerifyRecaptcha',
583        method: 'GET',
584        headers: { 'X-Recaptcha-Token': token },
585        success: function (data) {
586            if (data.d === true) {
587                FinishOrder();
588            } else {
589                customNotify({ message: 'Verifikacija nije uspela. Molimo pokušajte ponovo.', type: 'error' });
590                $('#ButtonCheck').removeClass('loading');
591                if (recaptchaBasketWidgetId !== undefined) {
592                    grecaptcha.reset(recaptchaBasketWidgetId);
593                }
594            }
595        },
596        error: function () {
597            customNotify({ message: 'Greška pri verifikaciji. Molimo pokušajte ponovo.', type: 'error' });
598            $('#ButtonCheck').removeClass('loading');
599            if (recaptchaBasketWidgetId !== undefined) {
600                grecaptcha.reset(recaptchaBasketWidgetId);
601            }
602        }
603    });
604}
605
606function ValidateOrder(btn) {
607
608    $('.single-product input').removeClass('border-danger');
609    $('.single-product .error-msg').remove();
610
611    var Validation = true;
612    const basketTotal = parseFloat(document.getElementById('basket-total').dataset.baskettotal);
613
614    if ($("#terms_agree").prop("checked") == false) {
615        $("#terms_agree").addClass("require-data");
616        alert("Morate prihvatiti uslove korišćenja.");
617
618    }
619    else if (MasterJson.MinimumOrderValue > 0 && basketTotal < MasterJson.MinimumOrderValue) {
620        Validation = false;
621        alert(`Minimalna vrednost porudžbine je ${MasterJson.MinimumOrderValue.toLocaleString('sr-RS', { style: 'currency', currency: 'RSD', minimumFractionDigits: 2, maximumFractionDigits: 2 })}. Molimo Vas da povećate vrednost porudžbine.`);
622    }
623    else if (!isEmail($('#txtEmail').val())) {
624        Validation = false;
625        $('#txtEmail').addClass('require-data');
626        alert('Uneta e-mail adresa nije ispravna. Molimo Vas da unesete ispravnu e-mail adresu.');
627    }
628    else {
629        $('#txtEmail').removeClass('require-data');
630        $("[data-require='true']:visible").each(function () {
631            if (!$(this).val()) {
632                console.log($(this).attr('id') + ": " + $(this).val());
633                $(this).addClass("require-data");
634                Validation = false;
635            }
636        });
637
638        if (!Validation) {
639            alert("Proverite unete podatke. Morate da popunite sva obavezna polja.");
640        }
641        else {
642            btn.classList.add('loading');
643            $.get("/Services/EcommerceService.svc/ValidateOrder", function (data) {
644                // console.log(data);
645                if (data.d.length == 0) {
646
647                    const Name = $('#txtName').val() || '';
648                    const CompanyName = $('#txtCompanyName').val() || '';
649                    const Street = $('#txtStreet').val();
650                    const StreetNumber = $('#txtStreetNumber').val();
651                    const Commune = $('#txtCommune').val();
652                    const City = $('#txtCity').val();
653                    const PostCode = $('#txtPostCode').val();
654                    const Phone = $('#txtPhone').val();
655                    const Email = $('#txtEmail').val();
656                    const Note = $('#txtNote').val();
657                    const CountryUid = $('#selectCountry').val();
658                    const CompanyID = $('#txtPIB').val() || '';
659
660                    $.ajax({
661                        url: '/Services/EcommerceService.svc/SaveUserBasketData',
662                        data: {Name, Street, StreetNumber, Commune, City, PostCode, Phone, Email, Note, CountryUid, CompanyName, CompanyID}
663                    })
664                    .done(function(res) {
665                        // console.log(res);
666                        if (res.d) {
667                            grecaptcha.execute(recaptchaBasketWidgetId);
668                        } else {
669                            console.log(res);
670                            btn.classList.remove('loading');
671                            alert('Greška u čuvanju podataka');
672                        }
673                    })
674                    .fail(function(err) {
675                        console.log(err);
676                        btn.classList.remove('loading');
677                        alert('Greška u čuvanju podataka');
678                    });
679
680                } else {
681                    const validationMessages = {
682                        'Basket-empty': 'korpa je prazna',
683                        'no-selected-payment-method': 'nije izabran način plaćanja',
684                        'no-selected-shipping-method': 'nije izabran način dostave',
685                        'no-shipping-address': 'adresa za dostavu nije izabrana'
686                    };
687                    const message = data.d.map(e => validationMessages[e] || e).join(', ');
688                    customNotify({message});
689                    btn.classList.remove('loading');
690                }
691            });
692        }
693    }
694
695}
696
697
698function calculateFreeShipping(freeShippingTreshold) {
699    const reminderContainer = document.querySelector('.free-shipping-reminder');
700    const basketTotal = parseFloat(document.getElementById('basket-total').dataset.baskettotal);
701    const razlika = freeShippingTreshold - basketTotal;
702    const razlikaRSD = razlika.toLocaleString('sr-RS', {
703        style: 'currency',
704        currency: 'RSD',
705        minimumFractionDigits: 2,
706        maximumFractionDigits: 2,
707    });
708
709    if (freeShippingTreshold && freeShippingTreshold > 0 && razlika > 0) {
710        reminderContainer.innerHTML = `
711            Za besplatnu dostavu nedostaje vam ${razlika < 500 ? 'samo' : ''} jo&#353; <strong>${razlikaRSD}</strong>. <a href="/">DODAJ PROIZVODE</a>
712        `;
713        $(reminderContainer).show();
714    }
715
716}
717
718function checkForShippingMap() {
719    const shipMap = document.querySelector('.shipping-wrapper iframe');
720    if (shipMap) {
721        $(shipMap).closest('.shipping-wrapper').find('.terms.description').append('<span class="map-show" data-toggle="modal" data-target="#show-map"><img src="/templates/B2C/skins/main/img/map.png" /></span>');
722        // $('.map-icon-container').html('<span class="map-show" data-toggle="modal" data-target="#show-map"><i class="fa fa-map-marker" aria-hidden="true"></i></span>');
723        $('#show-map .modal-body').html(shipMap);
724    }
725}
726
727function handleEmptyBasket() {
728    // console.log('handleEmptyBasket called');
729    // console.log(BasketBehaivorObj);
730    $('#basketContainer').html('');
731    $('#emptyBasketMsg').show();
732}
733
734function checkForLogin() {
735    // console.log('checkForLogin called');
736    const loginInfo = JSON.parse(sessionStorage.getItem('LoginInfo'));
737    if (loginInfo && loginInfo.v && loginInfo.v.IsLoggedIn) {
738        if (document.cookie.includes('userid')) {
739            let userEmail = document.cookie.split('userid=')[1].split('&')[0];
740            document.getElementById('txtEmail').value = userEmail;;
741            document.getElementById('txtEmail').disabled = true;
742        }
743    }
744}
745
746function analyticsBeginCheckout() {
747    try {
748        if (!CheckoutItems) throw new Error('No CheckoutItems obj in basket');
749
750        if (MasterJson.GAMeasurementID) {
751            gtag('event', 'begin_checkout', {
752                'value': CheckoutItems.ecommerce?.value,
753                'currency': CheckoutItems.ecommerce?.currency,
754                'items': CheckoutItems.ecommerce?.items,
755            });
756        }
757    } catch (err) {
758        console.log('"CheckoutItems" failed - basket.ascx');
759        console.log(err);
760    }
761}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.