Subversion Repositories SmartDukaan

Rev

Rev 36984 | Rev 37021 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
35548 aman 1
$(function () {
2
    $(document).on('click', ".lead", function () {
3
        loadLead("main-content");
4
    });
29598 tejbeer 5
 
35548 aman 6
    $(document).on('click', ".team-commitment", function () {
7
        loadTeamCommitment("main-content");
8
    });
30439 tejbeer 9
 
10
 
35548 aman 11
    $(document).on('click', ".partner-health", function () {
12
        loadPartnerHealth("main-content");
13
    });
29598 tejbeer 14
 
35548 aman 15
    $(document).on('click', ".lead-detail", function () {
16
        loadLeadDetail("main-content");
17
    });
30439 tejbeer 18
 
31370 tejbeer 19
 
35548 aman 20
    $(document).on('click', ".submitCommitment",
21
        function () {
22
            var startDateTime = getDatesFromPicker('input[name="commitmentDate"]').startDate;
23
            doGetAjaxRequestHandler(context + "/getTeamCommitment?date="
24
                + startDateTime, function (response) {
25
                $('.teamcommitmentcontainer').html(response);
31370 tejbeer 26
 
35548 aman 27
            });
28
        });
30439 tejbeer 29
 
30
 
35548 aman 31
    $(document).on('click', ".submitDateWiseLead", function () {
30439 tejbeer 32
 
35769 amit 33
        var startDate = $("#startDate").val();
34
        var endDate = $("#endDate").val();
35548 aman 35
        var status = $("#statusFilter").val();
36
        var color = $("#colorFilter").val();
31370 tejbeer 37
 
35548 aman 38
        if (color == null) {
39
            color = "";
40
        }
31370 tejbeer 41
 
35769 amit 42
        if (startDate && endDate) {
43
            var start = new Date(startDate);
44
            var end = new Date(endDate);
45
            if (end < start) {
46
                alert("End date must be after start date");
47
                return;
48
            }
49
        }
31370 tejbeer 50
 
35769 amit 51
        doGetAjaxRequestHandler(context + "/getOpenLead?leadStatus=" + status + "&color=" + color + "&startDate=" + startDate + "&endDate=" + endDate, function (response) {
35548 aman 52
            $('#' + 'main-content').html(response);
53
        });
29598 tejbeer 54
 
55
 
35548 aman 56
    })
57
    ;$(document).on('click', ".downloadDateWiseLead", function () {
29598 tejbeer 58
 
35769 amit 59
        var startDate = $("#startDate").val();
60
        var endDate = $("#endDate").val();
35548 aman 61
        var status = $("#statusFilter").val();
62
        var color = $("#colorFilter").val();
29598 tejbeer 63
 
35548 aman 64
        if (color == null) {
65
            color = "";
66
        }
29598 tejbeer 67
 
35769 amit 68
        if (startDate && endDate) {
69
            var start = new Date(startDate);
70
            var end = new Date(endDate);
71
            if (end < start) {
72
                alert("End date must be after start date");
73
                return;
74
            }
75
        }
76
 
77
        let endPoint = `${context}/downloadDateWiseLead?leadStatus=${status}&color=${color}&startDate=${startDate}&endDate=${endDate}`;
35548 aman 78
        window.location.href = endPoint;
31249 tejbeer 79
 
35548 aman 80
    });
34650 aman.kumar 81
 
36984 aman 82
    // Existing lead-table Search box: pressing Enter searches ALL leads (server-side) by
83
    // name / mobile / outlet / city, not just the rows already loaded. Typing still filters
84
    // the loaded rows via DataTables; clearing the box removes the global results.
85
    $(document).on('keydown', "#lead-table_filter input", function (e) {
86
        if (e.which === 13) {
87
            e.preventDefault();
88
            var term = $.trim($(this).val() || "");
89
            if (term === "") {
90
                $('#global-search-results').html("");
91
                return;
92
            }
93
            doGetAjaxRequestHandler(context + "/globalLeadSearch?searchTerm=" + encodeURIComponent(term),
94
                function (response) {
95
                    $('#global-search-results').html(response);
96
                });
97
        }
98
    });
34650 aman.kumar 99
 
36984 aman 100
    $(document).on('input', "#lead-table_filter input", function () {
101
        if ($.trim($(this).val() || "") === "") {
102
            $('#global-search-results').html("");
103
        }
104
    });
105
 
106
 
35548 aman 107
    $(document).on('click', ".visit-request-plan", function () {
34650 aman.kumar 108
 
35548 aman 109
        doGetAjaxRequestHandler(context + "/visitPlan", function (response) {
110
            $('#' + 'main-content').html(response);
111
        });
34650 aman.kumar 112
 
35548 aman 113
    });
34650 aman.kumar 114
 
35548 aman 115
    $(document).on('click', ".visitPlan", function () {
25980 tejbeer 116
 
35548 aman 117
        let dateWisePlan = $("#dateVisitSearch").val();
31249 tejbeer 118
 
35548 aman 119
        doGetAjaxRequestHandler(context + "/visit/getVisitPlan?date=" + dateWisePlan, function (response) {
120
            $('#' + 'main-content').html(response);
121
        });
31249 tejbeer 122
 
35548 aman 123
    });
31249 tejbeer 124
 
35548 aman 125
    $(document).on('click', ".lead-close", function () {
126
        loadClosedLead("main-content");
127
    });
31249 tejbeer 128
 
35548 aman 129
    $(document).on('click', "#lead-close-paginated .next",
130
        function () {
31249 tejbeer 131
 
35548 aman 132
            var searchText = $("#authUser").val();
133
            // var searchTxt=$("#scheme-search-text").val();
134
            console.log(searchText);
135
            if (typeof (searchText) == "undefined" || !searchText) {
136
                searchText = "";
137
            }
31249 tejbeer 138
 
35548 aman 139
            if ((searchText)) {
140
                var params = {};
141
                params['searchTerm'] = searchText;
142
                loadPaginatedNextItems('/searchLeadPaginated', params,
143
                    'lead-close-paginated', 'close-lead-table',
144
                    'lead-close-container');
145
            } else {
31249 tejbeer 146
 
35548 aman 147
                loadPaginatedNextItems('/getPaginatedClosedLeads', null,
148
                    'lead-close-paginated', 'close-lead-table',
149
                    'lead-close-container');
150
            }
151
            $(this).blur();
152
        });
31249 tejbeer 153
 
35548 aman 154
    $(document).on('click', "#lead-close-paginated .previous",
155
        function () {
156
            var searchText = $("#authUser").val();
157
            // var searchTxt=$("#scheme-search-text").val();
158
            console.log(searchText);
159
            if (typeof (searchText) == "undefined" || !searchText) {
160
                searchText = "";
161
            }
25988 tejbeer 162
 
35548 aman 163
            if ((searchText)) {
164
                var params = {};
165
                params['searchTerm'] = searchText;
166
                loadPaginatedPreviousItems('/searchLeadPaginated', params,
167
                    'lead-close-paginated', 'close-lead-table',
168
                    'lead-close-container');
169
            } else {
170
                loadPaginatedPreviousItems('/getPaginatedClosedLeads',
171
                    null, 'lead-close-paginated', 'close-lead-table',
172
                    'lead-close-container');
173
            }
174
            $(this).blur();
175
        });
25988 tejbeer 176
 
35548 aman 177
    $(document).on('click', "#close-lead-search-button", function () {
178
        var searchText = $("#authUser").val();
179
        if (typeof (searchText) == "undefined" || !searchText) {
180
            searchText = "";
181
        }
182
        loadLeadSearchInfo(searchText);
183
    });
25988 tejbeer 184
 
35548 aman 185
    $(document).on("keyup", "#authUser", function (e) {
186
        var keyCode = e.keyCode || e.which;
187
        if (keyCode == 13) {
188
            $("#close-lead-search-button").click();
189
        }
190
    });
191
    $(document).on('click', ".view",
192
        function () {
193
            var id = $(this).data('requestid');
194
            console.log(id);
195
            doGetAjaxRequestHandler(context + "/getLeadActivity?leadId="
196
                + id, function (response) {
25988 tejbeer 197
 
35548 aman 198
                console.log(response)
25988 tejbeer 199
 
35548 aman 200
                $('#fetchLeadActivityData .modal-content').html(response);
25988 tejbeer 201
 
35548 aman 202
            });
203
        });
25988 tejbeer 204
 
35548 aman 205
    $(document).on('click', ".newLead", function () {
206
        $('#newEntryLeadModal').modal('show');
207
        $("#scheduleTime").hide();
208
    });
25988 tejbeer 209
 
35548 aman 210
    $(document).on('click', ".show-lead", function () {
211
        var status = $("#statusFilter").val();
212
        doGetAjaxRequestHandler(context + "/getOpenLead?leadStatus=" + status, function (response) {
213
            $('#' + 'main-content').html(response);
214
        });
215
    });
25980 tejbeer 216
 
31370 tejbeer 217
 
35548 aman 218
    $(document).on('click', ".show-colowise-lead", function () {
219
        var status = $("#statusFilter").val();
220
        var color = $("#colorFilter").val();
221
        doGetAjaxRequestHandler(context + "/getOpenLead?leadStatus=" + status + "&color=" + color, function (response) {
222
            $('#' + 'main-content').html(response);
223
        });
224
    });
25980 tejbeer 225
 
35548 aman 226
    $(document).on('click', "#uploadIvoryLead", function () {
25980 tejbeer 227
 
35548 aman 228
        window.location.href = context + "/downloadIvoryLead";
229
    });
25980 tejbeer 230
 
35548 aman 231
    $(document).on('click', ".submitLeadGenerate", function () {
27609 tejbeer 232
 
35548 aman 233
        console.log("hello");
234
        if (confirm('Confirm upload ?')) {
235
            var fileSelector = $(this)[0];
236
            if (fileSelector != undefined) {
237
                var url = `${context}/csvFileAndSetLead`;
238
                console.log(url);
239
                var file = $(".fileLeadGenerate")[0].files[0];
240
                let fileInput = $(this);
241
                console.log("file" + file);
242
                console.log("fileInput" + fileInput);
243
                doAjaxUploadRequestHandler(
244
                    url,
245
                    'POST',
246
                    file, function (response) {
27642 tejbeer 247
 
35548 aman 248
                        console.log("reponse" + response);
31370 tejbeer 249
 
35548 aman 250
                        if (response == true) {
251
                            alert("successfully uploaded");
31370 tejbeer 252
 
253
 
35548 aman 254
                        }
255
                    });
29598 tejbeer 256
 
35548 aman 257
            }
258
        } else {
259
            // Do nothing!
260
        }
261
    });
27642 tejbeer 262
 
263
 
35548 aman 264
    $(document).on('click', ".lead-request",
265
        function () {
29598 tejbeer 266
 
35548 aman 267
            var firstName = $('input[name="firstName"]').val();
268
            var lastName = $('input[name="lastName"]').val();
269
            var mobile = $('input[name="mobile"]').val();
270
            var address = $('input[name="address"]').val();
271
            var status = $("#status").val();
272
            var city = $('input[name="city"]').val();
273
            var state = $("#state").val();
274
            var remark = $("#createRemark").val();
275
            var assignTo = $("#createAssignTo").val();
276
            var source = $("#leadSource").val();
277
            var communicationType = $("#communicationTye").val();
29427 manish 278
 
35548 aman 279
            var conversionprobability = $("#conversionprobabilit").val();
29598 tejbeer 280
 
281
 
35548 aman 282
            var outletName = $('input[name="leadoutletName"]').val();
283
            var counterSize = $('input[name="leadcounterSize"]').val();
284
            var table = document.getElementById('brandtable');
285
            var brandValueJson = [];
286
            var leadBrands;
29598 tejbeer 287
 
35548 aman 288
            console.log(conversionprobability)
29598 tejbeer 289
 
290
 
35548 aman 291
            if (firstName === "" && lastName === "" && mobile === ""
292
                && address === "" && status === "" && city === ""
293
                && state === "" && remark === "" && source === "") {
294
                alert("Field can't be empty");
295
                return;
296
            }
29598 tejbeer 297
 
25980 tejbeer 298
 
35548 aman 299
            if (firstName === "") {
300
                alert("First Name is required");
301
                return;
302
            }
303
            if (lastName === "") {
304
                alert("Last Name is required");
305
                return;
306
            }
307
            if (mobile === "") {
308
                alert("Mobile is required");
309
                return;
310
            }
311
            if (status === "") {
312
                alert("Status is required");
313
                return;
314
            }
315
            if (address === "") {
316
                alert("address is required");
317
                return;
318
            }
319
            if (city === "") {
320
                alert("city is required");
321
                return;
322
            }
32471 tejbeer 323
 
35548 aman 324
            if (state === "") {
325
                alert("state is required");
326
                return;
327
            }
328
            if (source === "") {
329
                alert("Source is required")
330
                return;
331
            }
32471 tejbeer 332
 
35548 aman 333
            if (remark === "") {
334
                alert("Remark is required");
335
                return;
336
            }
32471 tejbeer 337
 
35548 aman 338
            if (conversionprobability === "") {
339
                alert("Conversion Probability is required");
340
                return;
341
            }
342
            if (status == "followUp" || status == "pending" || status == "finalized") {
343
                if (outletName === "") {
344
                    alert("Outlet Name is required");
345
                    return;
346
                }
25980 tejbeer 347
 
35548 aman 348
                if (counterSize === "") {
349
                    alert("Counter Size is required");
350
                    return;
351
                }
32464 tejbeer 352
 
35548 aman 353
                if (localStorage.getItem("frontph") == "undefined" && localStorage.getItem("frontph") == null) {
354
                    alert("Front Document is required");
355
                    return;
356
                }
32464 tejbeer 357
 
35548 aman 358
                if (localStorage.getItem("internalMarketh") == "undefined" || localStorage.getItem("internalMarketh") == null) {
359
                    alert("Front With Market Document is required");
360
                    return;
361
                }
25980 tejbeer 362
 
35548 aman 363
                if (localStorage.getItem("leftShoth") == "undefined" || localStorage.getItem("leftShoth") == null) {
364
                    alert("Internal Left Shot Document is required");
365
                    return;
366
                }
32464 tejbeer 367
 
35548 aman 368
                if (localStorage.getItem("leftWallh") == "undefined" || localStorage.getItem("leftWallh") == null) {
369
                    alert("Internal Left Wall Document is required");
370
                    return;
371
                }
25980 tejbeer 372
 
373
 
35548 aman 374
                if (localStorage.getItem("rightWallh") == "undefined" || localStorage.getItem("rightWallh") == null) {
375
                    alert("Internal Right Wall Document is required");
376
                    return;
377
                }
25980 tejbeer 378
 
32464 tejbeer 379
 
35548 aman 380
                for (i = 1; i < table.rows.length; i++) {
32464 tejbeer 381
 
35548 aman 382
                    var objCells = table.rows[i].cells;
32464 tejbeer 383
 
35548 aman 384
                    leadBrands = {
385
                        brand: objCells[0].innerText,
386
                        value: objCells[1].getElementsByTagName('input')[0].value
387
                    }
388
                    brandValueJson.push(leadBrands);
389
                }
32464 tejbeer 390
 
391
 
35548 aman 392
            }
32464 tejbeer 393
 
394
 
35548 aman 395
            var leaddetailData = {}
396
            leaddetailData['firstName'] = firstName;
397
            leaddetailData['lastName'] = lastName
398
            leaddetailData['mobile'] = mobile
399
            leaddetailData['address'] = address
400
            leaddetailData['city'] = city
401
            leaddetailData['state'] = state
402
            leaddetailData['status'] = status
403
            leaddetailData['remark'] = remark
404
            leaddetailData['assignTo'] = assignTo
405
            leaddetailData['source'] = source
406
            leaddetailData['colorCheck'] = conversionprobability
32464 tejbeer 407
 
408
 
35548 aman 409
            if (status == "followUp") {
410
                leaddetailData['schelduleTimestamp'] = getDatesFromPicker('#scheduleTime').startDate;
32464 tejbeer 411
 
35548 aman 412
                leaddetailData['communicationType'] = communicationType
413
            }
32464 tejbeer 414
 
415
 
35548 aman 416
            leaddetailData['outletName'] = outletName;
32464 tejbeer 417
 
35548 aman 418
            leaddetailData['counterSize'] = counterSize;
32464 tejbeer 419
 
420
 
35548 aman 421
            leaddetailData['leadBrands'] = brandValueJson;
32464 tejbeer 422
 
35548 aman 423
            console.log(localStorage.getItem("frontp"));
32464 tejbeer 424
 
425
 
35548 aman 426
            leaddetailData['frontp'] = localStorage
427
                .getItem("frontph");
31249 tejbeer 428
 
32464 tejbeer 429
 
35548 aman 430
            leaddetailData['frontWithMarket'] = localStorage
431
                .getItem("internalMarketh");
32464 tejbeer 432
 
433
 
35548 aman 434
            leaddetailData['internalLongShot'] = localStorage
435
                .getItem("leftShoth");
32464 tejbeer 436
 
437
 
35548 aman 438
            leaddetailData['internalLeftWall'] = localStorage
439
                .getItem("leftWallh");
32464 tejbeer 440
 
441
 
35548 aman 442
            leaddetailData['internalRightWall'] = localStorage
443
                .getItem("rightWallh");
32464 tejbeer 444
 
35548 aman 445
            console.log(leaddetailData);
32464 tejbeer 446
 
35548 aman 447
            if (confirm("Are you sure you want to add lead!") == true) {
448
                doPostAjaxRequestWithJsonHandler(context + "/createLead",
449
                    JSON.stringify(leaddetailData), function (response) {
450
                        if (response == 'true') {
451
                            alert("successfully Add");
452
                            $('#newEntryLeadModal').modal('hide');
453
                            $('.modal-backdrop').remove();
454
                            loadLead("main-content");
455
                        } else {
456
                            alert(response);
457
                        }
458
                    });
32464 tejbeer 459
 
35548 aman 460
                return false;
461
            }
462
        });
36642 ranu 463
    window.leadId = null;
35548 aman 464
    var row = null;
37003 ranu 465
    // Turn Assign To into a search-select. We attempt initialisation at 3 points to be
466
    // robust against ordering / DOM-timing issues:
467
    //   1. Immediately at load time (element is in DOM per lead.vm)
468
    //   2. On the modal's shown.bs.modal event (post-transition)
469
    //   3. As a fallback in the click handler with a small delay
470
    function initAssignToSelect2() {
471
        if (!$.fn.select2) {
472
            console.warn('[lead.js] select2 not loaded — falling back to native <select>');
473
            return;
474
        }
475
        var $assign = $('#assignTo');
476
        if ($assign.length === 0) return;
477
        if ($assign.hasClass('select2-hidden-accessible')) return; // already applied
478
        $assign.select2({
479
            placeholder: 'Assign To',
480
            allowClear: true,
481
            width: '100%',
482
            dropdownParent: $('#editLeadData'),
483
            // Hide disabled options — VISIT/TELEPHONIC filter uses .prop('disabled', true).
484
            matcher: function (params, data) {
485
                if (data.element && $(data.element).prop('disabled')) return null;
486
                if (!params.term || $.trim(params.term) === '') return data;
487
                if (data.text && data.text.toLowerCase().indexOf(params.term.toLowerCase()) > -1) return data;
488
                return null;
489
            }
490
        });
491
        console.log('[lead.js] select2 applied to #assignTo');
492
    }
493
 
494
    initAssignToSelect2();
495
    $(document).on('shown.bs.modal', '#editLeadData', initAssignToSelect2);
496
 
35548 aman 497
    $(document).on('click', ".editLead", function () {
498
        $('#editLeadData').modal('show');
37003 ranu 499
        // Belt-and-braces: also try after the modal transition completes.
500
        setTimeout(initAssignToSelect2, 300);
32464 tejbeer 501
 
35548 aman 502
        $("#remark").val("");
37003 ranu 503
        $("#assignTo").val("").trigger('change');
35548 aman 504
        $("#editStatus").val("");
505
        $("#reason").val("");
506
        $("#editCity").val("");
507
        $("#editState").val("");
35769 amit 508
        $("#editSource").val("");
35548 aman 509
        $("#editScheduleTime").hide();
32464 tejbeer 510
 
511
 
35548 aman 512
        localStorage.removeItem("frontph");
513
        localStorage.removeItem("leftShoth");
514
        localStorage.removeItem("rightWallh");
515
        localStorage.removeItem("leftWallh");
516
        localStorage.removeItem("internalMarketh");
32464 tejbeer 517
 
35548 aman 518
        row = $(this).closest("tr");
519
        leadId = $(this).data('leadid');
32464 tejbeer 520
 
35548 aman 521
        doAjaxRequestHandler(
522
            context + "/getLeadDetailByLeadId?leadId=" + leadId,
523
            "GET",
524
            function (response) {
32464 tejbeer 525
 
35548 aman 526
                var data = response.response;
527
                if (!data) return;
528
                console.log(data);
529
                $("#editCity").val(data.city);
530
                $("#editState").val(data.state);
531
                $("input[name='outletName']").val(data.outletName);
532
                $("input[name='counterSize']").val(data.counterSize);
533
            }
534
        );
535
    });
32464 tejbeer 536
 
537
 
35548 aman 538
    $(document).on('click', ".lead-edit-request",
539
        function () {
32464 tejbeer 540
 
36761 ranu 541
            // Gate the assign/status submit on approved geo. Modal stays open so the
542
            // user can still work the other sub-forms (lead detail, etc.).
543
            var clickedBtn = $(this);
36789 ranu 544
            // notInterested is a close-out — no geo / no beat / no assignee
545
            // needed. Skip the geo gate and submit straight through with just
546
            // the activity (status + reason + remark).
547
            var currentStatus = $('#editStatus').val();
548
            if (currentStatus === 'notInterested') {
549
                submitLeadEdit();
550
                return;
551
            }
36792 ranu 552
            // Non-sales assignees (BGC / other internal hand-offs) don't need
553
            // geo or a beat-day — the lead just routes to their queue. Skip the
554
            // geo gate and submit straight through, same as the legacy flow.
555
            var assigneeId = parseInt($('#assignTo').val(), 10);
556
            var isSalesAssignee = !isNaN(assigneeId)
557
                && typeof salesUserIds !== 'undefined'
558
                && salesUserIds.indexOf(assigneeId) !== -1;
559
            if (!isSalesAssignee) {
560
                submitLeadEdit();
561
                return;
562
            }
36761 ranu 563
            if (clickedBtn.data('geoChecking')) return;
564
            clickedBtn.data('geoChecking', true);
565
            doAjaxRequestHandler(
566
                context + "/lead-geo/check/" + leadId,
567
                "GET",
568
                function (response) {
569
                    clickedBtn.removeData('geoChecking');
570
                    var hasGeo = response && response.response && response.response.hasApprovedGeo;
571
                    if (!hasGeo) {
572
                        alert('Live geo-location for this lead has not been approved yet. Please approve the geo-location before assigning / updating status.');
573
                        return;
574
                    }
575
                    submitLeadEdit();
576
                }
577
            );
578
        });
25980 tejbeer 579
 
36761 ranu 580
    function submitLeadEdit() {
581
 
35548 aman 582
            console.log(row);
583
            var remark = $('input[name="remark"]').val();
584
            var assignTo = $("#assignTo").val();
585
            var editStatus = $("#editStatus").val();
586
            var city = $('input[name="editCity"]').val();
587
            var state = $("#editState").val();
588
            var reason = $("#reason").val();
25980 tejbeer 589
 
35769 amit 590
            var startDate = $("#startDate").val();
591
            var endDate = $("#endDate").val();
35548 aman 592
            var leadStatus = $("#statusFilter").val();
593
            var color = $("#colorFilter").val();
594
            var communicationType = $("#communicationType").val();
29640 tejbeer 595
 
35548 aman 596
            var conversionprobability = $("#conversionprobability").val();
35769 amit 597
            var editSource = $("#editSource").val();
29640 tejbeer 598
 
35548 aman 599
            console.log(conversionprobability)
29640 tejbeer 600
 
31473 tejbeer 601
 
35769 amit 602
            console.log(startDate)
35548 aman 603
            console.log(leadStatus)
31370 tejbeer 604
 
35548 aman 605
            console.log(color)
606
            console.log(reason)
31370 tejbeer 607
 
35548 aman 608
            if (remark === "" && assignTo === "" && editStatus === "") {
609
                alert("All fields is required");
610
                return;
611
            }
31370 tejbeer 612
 
36789 ranu 613
        // For notInterested (close-out) the lead doesn't need an assignee
614
        // — it's just a status + reason + remark write. Only enforce
615
        // assignTo for the other statuses where scheduling matters.
616
        if (assignTo === "" && editStatus !== "notInterested") {
35548 aman 617
                alert("assignTo is required");
618
                return;
619
            }
31409 tejbeer 620
 
35548 aman 621
            if (remark === "") {
622
                alert("Remark is required");
623
                return;
624
            }
31370 tejbeer 625
 
626
 
35548 aman 627
            if (editStatus === "") {
628
                alert("status is required");
629
                return;
630
            }
31370 tejbeer 631
 
35548 aman 632
            if (editStatus === "notInterested") {
36789 ranu 633
                if (reason == null || reason === "") {
35548 aman 634
                    alert("Reason  is required");
635
                    return;
636
                }
637
            }
638
            var leadActivityData = {}
639
            leadActivityData['id'] = leadId;
640
            leadActivityData['remark'] = remark;
641
            leadActivityData['assignTo'] = assignTo
642
            leadActivityData['status'] = editStatus
643
            leadActivityData['reason'] = reason
36741 ranu 644
            leadActivityData['colorCheck'] = (conversionprobability === "true" || conversionprobability === true)
35548 aman 645
            if (city && city.trim() !== "") {
646
                leadActivityData.city = city;
647
            }
25980 tejbeer 648
 
35548 aman 649
            if (state && state.trim() !== "") {
650
                leadActivityData.state = state;
651
            }
29473 manish 652
 
35769 amit 653
            if (editSource && editSource.trim() !== "") {
654
                leadActivityData.source = editSource;
655
            }
29598 tejbeer 656
 
35769 amit 657
 
35548 aman 658
            if (editStatus == "followUp") {
36642 ranu 659
                leadActivityData['communicationType'] = communicationType
36792 ranu 660
                var assigneeIdForBeat = parseInt(assignTo, 10);
661
                var isSalesAssigneeForBeat = !isNaN(assigneeIdForBeat)
662
                    && typeof salesUserIds !== 'undefined'
663
                    && salesUserIds.indexOf(assigneeIdForBeat) !== -1;
36741 ranu 664
                var beatVal = $('#beatDate').val();
36792 ranu 665
                // Beat-day gate only applies to sales assignees. Non-sales
666
                // (BGC / other) hand-offs are just routed to the user's queue
667
                // without a beat attachment — same as the legacy flow.
668
                if (isSalesAssigneeForBeat) {
669
                    if (!beatVal) {
670
                        var hasBadges = $('#beatBadges .beat-badge').length > 0;
671
                        if (!hasBadges) {
672
                            alert('No upcoming beat is available for this assignee. Cannot schedule the lead until they have a beat.');
673
                        } else {
674
                            alert('Please select a beat date for the assignee before submitting.');
675
                        }
676
                        return;
36761 ranu 677
                    }
36792 ranu 678
                    var beatDate = beatVal.split('|')[0];
679
                    leadActivityData['scheldule'] = beatDate + 'T12:00:00';
680
                    leadActivityData['beatSelection'] = beatVal;
36642 ranu 681
                }
35548 aman 682
            }
29598 tejbeer 683
 
35548 aman 684
            console.log(leadActivityData);
685
            if (confirm("Are you sure you want to add lead!") == true) {
686
                doPostAjaxRequestWithJsonHandler(context + "/editLead", JSON.stringify(leadActivityData), function (response) {
687
                    console.log(response);
688
                    $('#editLeadData').modal('hide');
689
                    $('.modal-backdrop').remove();
690
                    row.html(response);
691
                });
692
            }
29598 tejbeer 693
 
36761 ranu 694
    }
32477 tejbeer 695
 
696
 
35548 aman 697
    $(document).on('click', ".show-partner-health",
698
        function () {
29598 tejbeer 699
 
35548 aman 700
            var email = $("#authUserFilter").val();
25980 tejbeer 701
 
35548 aman 702
            console.log(email)
703
            doGetAjaxRequestHandler(context + "/partnerHealth?email="
704
                + email, function (response) {
705
                console.log(response)
706
                $('#' + 'main-content').html(response);
25980 tejbeer 707
 
35548 aman 708
            });
709
        });
25980 tejbeer 710
 
711
 
35548 aman 712
    $(document).on('click', ".lead-detail-entry",
713
        function () {
28200 tejbeer 714
 
35548 aman 715
            console.log("hello");
716
            var outletName = $('input[name="outletName"]').val();
717
            var counterSize = $('input[name="counterSize"]').val();
718
            var table = document.getElementById('editbrandtable');
719
            var brandValueJson = [];
720
            var leadBrands;
25980 tejbeer 721
 
35548 aman 722
            if (outletName === "") {
723
                alert("Outlet Name is required");
724
                return;
725
            }
29598 tejbeer 726
 
35548 aman 727
            if (counterSize === "") {
728
                alert("Counter Size is required");
729
                return;
730
            }
32471 tejbeer 731
 
35548 aman 732
            if (localStorage.getItem("frontph") == "undefined" && localStorage.getItem("frontph") == null) {
733
                alert("Front Document is required");
734
                return;
735
            }
31249 tejbeer 736
 
35548 aman 737
            if (localStorage.getItem("internalMarketh") == "undefined" || localStorage.getItem("internalMarketh") == null) {
738
                alert("Front With Market Document is required");
739
                return;
740
            }
25980 tejbeer 741
 
35548 aman 742
            if (localStorage.getItem("leftShoth") == "undefined" || localStorage.getItem("leftShoth") == null) {
743
                alert("Internal Left Shot Document is required");
744
                return;
745
            }
27605 tejbeer 746
 
35548 aman 747
            if (localStorage.getItem("leftWallh") == "undefined" || localStorage.getItem("leftWallh") == null) {
748
                alert("Internal Left Wall Document is required");
749
                return;
750
            }
27605 tejbeer 751
 
30185 tejbeer 752
 
35548 aman 753
            if (localStorage.getItem("rightWallh") == "undefined" || localStorage.getItem("rightWallh") == null) {
754
                alert("Internal Right Wall Document is required");
755
                return;
756
            }
30185 tejbeer 757
 
758
 
35548 aman 759
            for (i = 1; i < table.rows.length; i++) {
30185 tejbeer 760
 
35548 aman 761
                var objCells = table.rows[i].cells;
30185 tejbeer 762
 
35548 aman 763
                leadBrands = {
764
                    brand: objCells[0].innerText,
765
                    value: objCells[1].getElementsByTagName('input')[0].value
766
                }
767
                brandValueJson.push(leadBrands);
768
            }
30185 tejbeer 769
 
30416 tejbeer 770
 
35548 aman 771
            var leadDetailObject = {};
31402 tejbeer 772
 
35548 aman 773
            leadDetailObject['leadId'] = leadId;
30416 tejbeer 774
 
775
 
35548 aman 776
            leadDetailObject['outletName'] = outletName;
31370 tejbeer 777
 
35548 aman 778
            leadDetailObject['counterSize'] = counterSize;
31370 tejbeer 779
 
35548 aman 780
            leadDetailObject['leadBrands'] = brandValueJson;
31370 tejbeer 781
 
31402 tejbeer 782
 
35548 aman 783
            console.log(localStorage.getItem("frontp"));
31402 tejbeer 784
 
785
 
35548 aman 786
            leadDetailObject['frontp'] = localStorage
787
                .getItem("frontph");
31402 tejbeer 788
 
789
 
35548 aman 790
            leadDetailObject['frontWithMarket'] = localStorage
791
                .getItem("internalMarketh");
31370 tejbeer 792
 
793
 
35548 aman 794
            leadDetailObject['internalLongShot'] = localStorage
795
                .getItem("leftShoth");
31370 tejbeer 796
 
797
 
35548 aman 798
            leadDetailObject['internalLeftWall'] = localStorage
799
                .getItem("leftWallh");
31370 tejbeer 800
 
801
 
35548 aman 802
            leadDetailObject['internalRightWall'] = localStorage
803
                .getItem("rightWallh");
31370 tejbeer 804
 
35548 aman 805
            console.log(leadDetailObject);
31370 tejbeer 806
 
35548 aman 807
            if (confirm("Are you sure you want to add lead detail!") == true) {
808
                doPostAjaxRequestWithJsonHandler(context + "/leadDetail", JSON.stringify(leadDetailObject), function (response) {
809
                    console.log(response);
810
                    if (response == 'true') {
811
                        alert("Submit Successfully");
812
                    }
31370 tejbeer 813
 
35548 aman 814
                });
815
            }
31370 tejbeer 816
 
35548 aman 817
        });
31370 tejbeer 818
 
819
 
35548 aman 820
    $(document).on('change', '.frontp',
821
        function () {
31370 tejbeer 822
 
35548 aman 823
            if (confirm('Document has been selected, Do you want to upload ?')) {
31370 tejbeer 824
 
35548 aman 825
                var documentId = uploadImage(this, "frontph");
31370 tejbeer 826
 
827
 
35548 aman 828
            } else {
31370 tejbeer 829
 
35548 aman 830
            }
831
        });
31456 tejbeer 832
 
35548 aman 833
    $(document).on('change', '.internalMarket',
834
        function () {
31456 tejbeer 835
 
35548 aman 836
            if (confirm('Document has been selected, Do you want to upload ?')) {
31456 tejbeer 837
 
35548 aman 838
                var documentId = uploadImage(this, "internalMarketh");
31456 tejbeer 839
 
35548 aman 840
            } else {
31456 tejbeer 841
 
35548 aman 842
            }
843
        });
31370 tejbeer 844
 
35548 aman 845
    $(document).on('change', '.leftShot',
31370 tejbeer 846
 
35548 aman 847
        function () {
848
            if (confirm('Document has been selected, Do you want to upload ?')) {
849
                var documentId = uploadImage(this, "leftShoth");
850
            } else {
31370 tejbeer 851
 
35548 aman 852
            }
853
        });
31370 tejbeer 854
 
35548 aman 855
    $(document).on('change', '.leftWall',
856
        function () {
857
            if (confirm('Document has been selected, Do you want to upload ?')) {
858
                var documentId = uploadImage(this, "leftWallh");
859
            } else {
31370 tejbeer 860
 
35548 aman 861
            }
862
        });
31370 tejbeer 863
 
35548 aman 864
    $(document).on('change', '.rightWall',
865
        function () {
866
            if (confirm('Document has been selected, Do you want to upload ?')) {
867
                var documentId = uploadImage(this, "rightWallh");
868
            } else {
869
            }
870
        });
31370 tejbeer 871
 
872
 
25980 tejbeer 873
});
874
 
31404 tejbeer 875
function uploadImage(fileSelector, attrName) {
35548 aman 876
    var documentId;
877
    if (fileSelector != undefined
878
        && fileSelector.files[0] != undefined) {
879
        var url = context
880
            + '/document-upload';
31370 tejbeer 881
 
35548 aman 882
        console.log(url);
883
        var file = fileSelector.files[0];
31370 tejbeer 884
 
35548 aman 885
        console.log(file)
886
        doAjaxUploadRequestHandler(
887
            url,
888
            'POST',
889
            file,
890
            function (response) {
891
                console.log(response)
892
                documentId = response.response.document_id;
893
                console
894
                    .log("documentId : "
895
                        + documentId);
31370 tejbeer 896
 
897
 
35548 aman 898
                localStorage
899
                    .setItem(
900
                        attrName,
901
                        documentId);
31402 tejbeer 902
 
35548 aman 903
            });
904
        return documentId;
905
    }
31370 tejbeer 906
 
907
}
908
 
909
 
25980 tejbeer 910
function loadLead(domId) {
35548 aman 911
    doGetAjaxRequestHandler(context + "/getOpenLead", function (response) {
912
        $('#' + domId).html(response);
913
    });
25980 tejbeer 914
}
915
 
25988 tejbeer 916
function loadClosedLead(domId, searchTerm) {
35548 aman 917
    doGetAjaxRequestHandler(context + "/getClosedLead", function (response) {
918
        $('#' + domId).html(response);
919
    })
25988 tejbeer 920
}
921
 
25980 tejbeer 922
function statusAction() {
35548 aman 923
    var val = $('#status').val();
924
    if (val == "followUp") {
925
        $("#scheduleTime").show();
926
    } else {
927
        $("#scheduleTime").hide();
928
    }
25980 tejbeer 929
 
930
}
27605 tejbeer 931
 
932
 
933
function editStatusAction() {
35548 aman 934
    var val = $('#editStatus').val();
935
    if (val == "followUp") {
36642 ranu 936
        // Show communication type and schedule date
937
        $("#communicationTypeSection").show();
35548 aman 938
        $("#editScheduleTime").show();
36642 ranu 939
        $("#beatDateSelection").hide();
940
 
36761 ranu 941
        // Reset communication type only; preserve the assignee the user picked.
36642 ranu 942
        $('#communicationType').val('');
37003 ranu 943
        $('#assignTo option').prop('disabled', false);
36642 ranu 944
 
945
        // Check if lead has approved geolocation to decide VISIT option
946
        doAjaxRequestHandler(context + "/lead-geo/check/" + leadId, "GET", function (response) {
947
            var hasGeo = response.response.hasApprovedGeo;
948
            var commDropdown = $('#communicationType');
949
            commDropdown.empty();
950
            commDropdown.append('<option value="" disabled selected>Communication Type</option>');
951
            commDropdown.append('<option value="TELEPHONIC">TELEPHONIC</option>');
952
            if (hasGeo) {
953
                commDropdown.append('<option value="VISIT">VISIT</option>');
954
            }
955
        });
35548 aman 956
    } else {
36642 ranu 957
        $("#communicationTypeSection").hide();
35548 aman 958
        $("#editScheduleTime").hide();
36642 ranu 959
        $("#beatDateSelection").hide();
37003 ranu 960
        $('#assignTo option').prop('disabled', false);
35548 aman 961
    }
27605 tejbeer 962
 
963
}
964
 
25988 tejbeer 965
function loadLeadSearchInfo(search_text) {
35548 aman 966
    loadSearchLead("main-content", search_text);
25988 tejbeer 967
}
968
 
30185 tejbeer 969
function loadTeamCommitment(domId) {
35548 aman 970
    doGetAjaxRequestHandler(context + "/teamCommitment",
971
        function (response) {
972
            $('#' + domId).html(response);
973
        });
30185 tejbeer 974
}
975
 
31370 tejbeer 976
function loadLeadDetail(domId) {
35548 aman 977
    doGetAjaxRequestHandler(context + "/getLeadDetail",
978
        function (response) {
979
            $('#' + domId).html(response);
980
        });
31370 tejbeer 981
}
982
 
30416 tejbeer 983
function loadPartnerHealth(domId) {
35548 aman 984
    doGetAjaxRequestHandler(context + "/partnerHealth",
985
        function (response) {
986
            $('#' + domId).html(response);
987
        });
30416 tejbeer 988
}
989
 
25988 tejbeer 990
function loadSearchLead(domId, search_text) {
35548 aman 991
    doGetAjaxRequestHandler(context + "/searchLeads?searchTerm=" + search_text,
992
        function (response) {
993
            $('#' + domId).html(response);
994
        });
25988 tejbeer 995
}
33917 ranu 996
 
997
$(document).on('click', ".arr-button-mk",
35548 aman 998
    function () {
999
        var startDate = $('.arr-start_date').val();
1000
        doGetAjaxRequestHandler(context + "/rbmTodayArr?startDate=" + startDate, function (response) {
1001
            $('#main-content').html(response);
33917 ranu 1002
 
35548 aman 1003
        });
1004
    });
33917 ranu 1005
 
1006
$(document).on('click', ".rbm-today-arr",
35548 aman 1007
    function () {
1008
        doGetAjaxRequestHandler(context + "/rbmTodayArr", function (response) {
1009
            $('#main-content').html(response);
33917 ranu 1010
 
35548 aman 1011
        });
1012
    });
1013
$(document).on('click', '.reassign', function () {
1014
    $('#bulkReassignFile').val(null);
1015
    $('#bulkReassignFile').click();
1016
});
1017
 
1018
$(document).on('change', '#bulkReassignFile', function () {
1019
 
1020
    if (!confirm("Confirm bulk reassign upload?")) {
1021
        return;
1022
    }
1023
 
1024
    var file = this.files[0];
1025
    if (!file) {
1026
        alert("No file selected");
1027
        return;
1028
    }
1029
 
1030
    doAjaxUploadRequestHandler(
1031
        context + "/upload-assign-id",
1032
        'POST',
1033
        file,
1034
        function (response) {
1035
            alert("Bulk reassignment completed");
1036
            loadLead("main-content");
1037
        }
1038
    );
1039
});
1040
 
36642 ranu 1041
// ==================== GEO LOCATION HANDLERS ====================
1042
 
1043
// Communication type change: filter assignTo based on type
1044
$(document).on('change', '#communicationType', function () {
1045
    var val = $(this).val();
1046
    var assignDropdown = $('#assignTo');
1047
 
36741 ranu 1048
    // Reset beat + restore manual date input
36642 ranu 1049
    $('#beatDate').val('');
1050
    $('#beatBadges').empty();
1051
    $("#beatDateSelection").hide();
36741 ranu 1052
    $("#editScheduleTime").show();
36642 ranu 1053
 
1054
    if (val == 'VISIT') {
37003 ranu 1055
        // Filter assignTo to sales users only (no BGC). Uses .prop('disabled', ...)
1056
        // instead of .hide()/.show() because select2 doesn't respect hidden <option>s
1057
        // in its dropdown UI. Disabled options are filtered out by our matcher above.
36642 ranu 1058
        if (typeof salesUserIds !== 'undefined') {
1059
            assignDropdown.find('option').each(function () {
1060
                var optVal = parseInt($(this).val());
1061
                if (optVal && salesUserIds.indexOf(optVal) === -1) {
37003 ranu 1062
                    $(this).prop('disabled', true);
36642 ranu 1063
                } else {
37003 ranu 1064
                    $(this).prop('disabled', false);
36642 ranu 1065
                }
1066
            });
1067
        }
1068
    } else {
37003 ranu 1069
        // TELEPHONIC — enable all users
1070
        assignDropdown.find('option').prop('disabled', false);
36642 ranu 1071
    }
37003 ranu 1072
    // Nudge select2 to re-render its dropdown with the new enabled/disabled state.
1073
    if ($.fn.select2 && assignDropdown.hasClass('select2-hidden-accessible')) {
1074
        assignDropdown.trigger('change.select2');
1075
    }
36741 ranu 1076
    // Both VISIT and TELEPHONIC offer beat-day slots when an assignee is set
1077
    // (TELEPHONIC just uses the beat date as the call slot; backend won't
1078
    // attach a LeadRoute for it). Non-sales assignees simply get an empty list.
1079
    if (val && assignDropdown.val()) {
1080
        fetchBeatDates();
1081
    }
36642 ranu 1082
});
1083
 
36741 ranu 1084
// Fetch beats when assignTo changes (works for both VISIT and TELEPHONIC)
1085
$(document).on('change', '#assignTo', function () {
36642 ranu 1086
    var commType = $('#communicationType').val();
1087
    var salesAuthId = $('#assignTo').val();
36741 ranu 1088
    if (commType && salesAuthId && leadId) {
36642 ranu 1089
        fetchBeatDates();
36741 ranu 1090
    } else if (!commType) {
36642 ranu 1091
        $("#beatDateSelection").hide();
1092
    }
1093
});
1094
 
1095
function fetchBeatDates() {
1096
    var salesAuthId = $('#assignTo').val();
1097
    if (!salesAuthId || !leadId) return;
1098
 
36792 ranu 1099
    // Beat slots only make sense for sales assignees. BGC / other internal
1100
    // hand-offs skip the entire beat panel (and the visit-request CTA that
1101
    // sits inside it). Mirrors the server-side carve-out in /editLead.
1102
    var assigneeIntId = parseInt(salesAuthId, 10);
1103
    var isSalesAssigneeFetch = !isNaN(assigneeIntId)
1104
        && typeof salesUserIds !== 'undefined'
1105
        && salesUserIds.indexOf(assigneeIntId) !== -1;
1106
    if (!isSalesAssigneeFetch) {
1107
        $('#beatBadges').empty();
1108
        $('#beatDate').val('');
1109
        $('#beatDateSelection').hide();
1110
        return;
1111
    }
1112
 
36642 ranu 1113
    var badgesDiv = $('#beatBadges');
1114
    badgesDiv.html('<span style="color:#999; font-size:12px;">Loading beats...</span>');
1115
    $("#beatDateSelection").show();
1116
    $('#beatDate').val('');
1117
 
1118
    var url = context + "/lead-geo/beat-dates?leadId=" + leadId + "&salesAuthId=" + salesAuthId;
1119
 
1120
    $.ajax({
1121
        url: url,
1122
        method: 'GET',
1123
        success: function (response) {
1124
            var data = response.response || response;
1125
            badgesDiv.empty();
36644 ranu 1126
 
36741 ranu 1127
            // Stores within radius of the lead — show count + top 3 inline.
1128
            var radius = (data && data.radiusKm) ? data.radiusKm : 30;
1129
            var stores = (data && data.nearestStores) || [];
1130
            if (stores.length > 0) {
1131
                var preview = stores.slice(0, 3).map(function (s) {
1132
                    return '<strong>' + s.code + ' - ' + s.name + '</strong> (' + s.distanceKm + ' km)';
1133
                }).join(', ');
1134
                var more = stores.length > 3 ? ' +' + (stores.length - 3) + ' more' : '';
36644 ranu 1135
                badgesDiv.append('<div style="font-size:12px; color:#333; margin-bottom:6px;">' +
36741 ranu 1136
                    stores.length + ' partner store(s) within ' + radius + ' km of this lead: ' +
1137
                    preview + more + '</div>');
36644 ranu 1138
            }
1139
 
36741 ranu 1140
            // All upcoming beat-dates for the assignee that touch any nearby store.
36642 ranu 1141
            if (data && data.beats && data.beats.length > 0) {
36644 ranu 1142
                badgesDiv.append('<div style="font-weight:bold; font-size:11px; color:#666; margin-bottom:4px;">Available Slots (near this lead):</div>');
36741 ranu 1143
                var beats = data.beats;
36642 ranu 1144
                for (var i = 0; i < beats.length; i++) {
1145
                    var beat = beats[i];
36644 ranu 1146
                    var nearTxt = beat.nearStore ? ' &middot; near ' + beat.nearStore : '';
36642 ranu 1147
                    var badge = $('<span class="beat-badge" style="' +
1148
                        'display:inline-block; background:#337ab7; color:#fff; padding:6px 12px; ' +
1149
                        'margin:4px 6px 4px 0; border-radius:16px; cursor:pointer; font-size:12px; ' +
1150
                        'border:2px solid #337ab7; transition:all 0.2s;">' +
36644 ranu 1151
                        beat.planDate + ' &middot; ' + beat.beatName + ' (' + beat.stops + ' stops)' + nearTxt +
36642 ranu 1152
                        '</span>');
1153
                    badge.data('value', beat.planDate + '|' + beat.beatName + '|' + beat.planGroupId);
1154
                    badgesDiv.append(badge);
1155
                }
1156
            } else {
36787 ranu 1157
                // No beat-days available for this assignee. Surface a CTA so the
1158
                // user can fire a visit request to the assignee's hierarchy instead
1159
                // of being stuck. The pre-existing 'beats > 0' branch above is
1160
                // untouched — this only fires for the empty-beats case.
1161
                var nearestId = (stores.length > 0 && stores[0].storeId) ? stores[0].storeId : '';
1162
                badgesDiv.append(
1163
                    '<div style="background:#fff8e1; border:1px solid #f0e0a0; border-radius:6px; padding:8px 10px; margin-top:4px;">'
1164
                    + '<div style="font-size:12px; color:#7c5a00; margin-bottom:6px;">'
1165
                    + 'No upcoming beat is available for this assignee.'
1166
                    + '</div>'
1167
                    + '<div style="display:flex; gap:8px; align-items:center;">'
1168
                    + '<label style="font-size:11px; color:#666; margin:0;">Preferred date (optional):</label>'
1169
                    + '<input type="date" id="vrPreferredDate" class="input-sm" style="font-size:12px; padding:3px 6px;">'
1170
                    + '<button type="button" id="vrSendBtn" class="btn btn-warning btn-sm" '
1171
                    + 'data-nearest="' + nearestId + '" style="font-size:12px;">Send Visit Request</button>'
1172
                    + '</div>'
1173
                    + '<div style="font-size:11px; color:#888; margin-top:6px;">'
1174
                    + 'The request goes to the assignee\'s reporting head (and up). Once they approve and pick a beat-day, the lead lands on that beat.'
1175
                    + '</div>'
1176
                    + '</div>');
36642 ranu 1177
            }
1178
        },
1179
        error: function () {
1180
            badgesDiv.html('<span style="color:#d9534f; font-size:12px;">Error loading beats</span>');
1181
        }
1182
    });
1183
}
1184
 
36787 ranu 1185
// Send Visit Request when no beats are available for the chosen assignee.
1186
// Posts to /visitRequest/create. Existing beat-pick + Submit flow is unchanged.
1187
$(document).on('click', '#vrSendBtn', function () {
1188
    var $btn = $(this);
1189
    var assigneeAuthId = parseInt($('#assignTo').val());
1190
    var commType = $('#communicationType').val() || null;
1191
    var nearestStoreId = parseInt($btn.data('nearest'));
1192
    var preferred = $('#vrPreferredDate').val() || null;
1193
    if (!leadId || !assigneeAuthId) {
1194
        alert('Pick an assignee first.');
1195
        return;
1196
    }
1197
    $btn.prop('disabled', true).text('Sending...');
1198
    var payload = {
1199
        leadId: leadId,
1200
        assigneeAuthId: assigneeAuthId,
1201
        communicationType: commType,
1202
        reason: 'No upcoming beats for assignee'
1203
    };
1204
    if (!isNaN(nearestStoreId) && nearestStoreId > 0) payload.nearestStoreId = nearestStoreId;
1205
    if (preferred) payload.requestedDate = preferred;
1206
 
1207
    doPostAjaxRequestWithJsonHandler(context + '/visitRequest/create', JSON.stringify(payload),
1208
        function (response) {
1209
            $btn.prop('disabled', false).text('Send Visit Request');
1210
            var data = (response && response.response) || response || {};
1211
            if (data && data.id) {
1212
                alert('Visit request sent. The assignee\'s manager has been notified.');
1213
                $('#editLeadData').modal('hide');
1214
                $('.modal-backdrop').remove();
1215
            } else {
1216
                var msg = (data && data.message) || (data && data.error) || 'Could not send request.';
1217
                alert(msg);
1218
            }
1219
        });
1220
});
1221
 
36741 ranu 1222
// Click on beat badge to select it. A picked beat becomes the schedule
1223
// source — the manual date input is hidden (not needed when scheduling by beat).
36642 ranu 1224
$(document).on('click', '.beat-badge', function () {
1225
    $('.beat-badge').css({'background': '#337ab7', 'border-color': '#337ab7'});
1226
    $(this).css({'background': '#1a5276', 'border-color': '#f39c12', 'border-width': '2px'});
1227
    $('#beatDate').val($(this).data('value'));
36741 ranu 1228
    $("#editScheduleTime").hide();
36642 ranu 1229
});
1230
 
1231
// Generate Geo Link for lead
1232
$(document).on('click', '.generateGeoLink', function (e) {
1233
    e.stopPropagation();
1234
    var lid = $(this).data('leadid');
1235
    doAjaxRequestHandler(context + "/lead-geo/generate-link?leadId=" + lid, "GET", function (response) {
1236
        var url = response.response;
1237
        if (navigator.clipboard) {
1238
            navigator.clipboard.writeText(url).then(function () {
1239
                alert("Link copied to clipboard:\n" + url);
1240
            });
1241
        } else {
1242
            prompt("Share this link with the prospect:", url);
1243
        }
1244
    });
1245
});
1246
 
36868 ranu 1247
// Manual geo verification — for cases where the prospect refused to tap the
1248
// verification link. Team-member confirms lat/lng over phone (or pastes a
1249
// Maps URL the prospect shared) and writes it APPROVED directly.
1250
function ensureManualVerifyModal() {
1251
    if ($('#manualVerifyGeoModal').length) return;
1252
    var html =
1253
        '<div id="manualVerifyGeoModal" class="modal" role="dialog" tabindex="-1">' +
1254
        '  <div class="modal-dialog modal-lg">' +
1255
        '    <div class="modal-content">' +
1256
        '      <div class="modal-header">' +
1257
        '        <button type="button" class="close" data-dismiss="modal">&times;</button>' +
1258
        '        <h4 class="modal-title">Verify Lead Location Manually</h4>' +
1259
        '      </div>' +
1260
        '      <div class="modal-body" style="max-height:75vh;overflow-y:auto;">' +
1261
        '        <input type="hidden" id="manualVerifyLeadId">' +
1262
        '        <div class="form-group">' +
1263
        '          <label>Address <small class="text-muted">(include city, state, pincode for best result)</small></label>' +
1264
        '          <div class="input-group">' +
1265
        '            <input type="text" class="form-control" id="manualVerifyAddress" placeholder="e.g. Shop 12, Sector 18, Noida, UP, 201301">' +
1266
        '            <span class="input-group-btn">' +
1267
        '              <button type="button" class="btn btn-default" id="manualVerifyGeocodeBtn">Find on map</button>' +
1268
        '            </span>' +
1269
        '          </div>' +
1270
        '        </div>' +
1271
        '        <div class="form-group">' +
1272
        '          <label>Latitude, Longitude</label>' +
1273
        '          <div class="input-group">' +
1274
        '            <input type="text" class="form-control" id="manualVerifyLatLng" placeholder="28.6139,77.2090">' +
1275
        '            <span class="input-group-btn">' +
1276
        '              <button type="button" class="btn btn-default" id="manualVerifyPreviewBtn">Show on map</button>' +
1277
        '            </span>' +
1278
        '          </div>' +
1279
        '          <small class="text-muted">You can also paste a Google Maps URL containing coords.</small>' +
1280
        '        </div>' +
1281
        '        <div class="form-group" id="manualVerifyMapWrap" style="display:none;">' +
1282
        '          <label>Map preview <small class="text-muted">(confirm the pin is right)</small></label>' +
1283
        '          <div style="border:1px solid #ddd;border-radius:3px;overflow:hidden;">' +
1284
        '            <iframe id="manualVerifyMapFrame" width="100%" height="260" frameborder="0" style="border:0;" allowfullscreen></iframe>' +
1285
        '          </div>' +
1286
        '          <small><a href="#" id="manualVerifyOpenMap" target="_blank">Open in Google Maps</a></small>' +
1287
        '        </div>' +
1288
        '        <div class="form-group">' +
1289
        '          <label>Store-board photo <span class="text-danger">*</span> <small class="text-muted">(required &mdash; proves the verification)</small></label>' +
1290
        '          <input type="file" id="manualVerifyPhoto" accept="image/jpeg,image/png" required>' +
1291
        '          <div id="manualVerifyPhotoPreview" style="margin-top:6px;display:none;">' +
1292
        '            <img id="manualVerifyPhotoImg" src="" style="max-height:120px;border:1px solid #ddd;border-radius:3px;padding:2px;">' +
1293
        '          </div>' +
1294
        '        </div>' +
1295
        '        <div class="form-group">' +
1296
        '          <label>Remark <small class="text-muted">(optional)</small></label>' +
1297
        '          <input type="text" class="form-control" id="manualVerifyRemark" placeholder="e.g. Confirmed on call with prospect">' +
1298
        '        </div>' +
1299
        '        <div id="manualVerifyErr" class="text-danger" style="display:none;"></div>' +
1300
        '      </div>' +
1301
        '      <div class="modal-footer">' +
1302
        '        <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>' +
1303
        '        <button type="button" class="btn btn-success" id="manualVerifySaveBtn">Save &amp; Verify</button>' +
1304
        '      </div>' +
1305
        '    </div>' +
1306
        '  </div>' +
1307
        '</div>';
1308
    $('body').append(html);
1309
}
1310
 
1311
function manualVerifyShowMap(lat, lng) {
1312
    var src = 'https://www.google.com/maps?q=' + lat + ',' + lng + '&z=17&output=embed';
1313
    $('#manualVerifyMapFrame').attr('src', src);
1314
    $('#manualVerifyOpenMap').attr('href', 'https://www.google.com/maps?q=' + lat + ',' + lng);
1315
    $('#manualVerifyMapWrap').show();
1316
}
1317
 
1318
// Parses raw "lat,lng" or a Google Maps URL containing the coords.
1319
// Maps formats covered: /@lat,lng, /maps?q=lat,lng, ?ll=lat,lng, ?destination=lat,lng.
1320
function parseLatLngInput(raw) {
1321
    if (!raw) return null;
1322
    var s = String(raw).trim();
1323
    // Strip any leading "lat:" / "lng:" tokens
1324
    var direct = s.match(/(-?\d{1,3}\.\d+)\s*,\s*(-?\d{1,3}\.\d+)/);
1325
    if (direct) return {lat: parseFloat(direct[1]), lng: parseFloat(direct[2])};
1326
    return null;
1327
}
1328
 
1329
$(document).on('click', '.verifyGeoManual', function (e) {
1330
    e.stopPropagation();
1331
    var lid = $(this).data('leadid');
1332
    ensureManualVerifyModal();
1333
    $('#manualVerifyLeadId').val(lid);
1334
    $('#manualVerifyAddress').val('');
1335
    $('#manualVerifyLatLng').val('');
1336
    $('#manualVerifyRemark').val('');
1337
    $('#manualVerifyErr').hide().text('');
1338
    $('#manualVerifyMapWrap').hide();
1339
    $('#manualVerifyMapFrame').attr('src', '');
1340
    $('#manualVerifyPhoto').val('');
1341
    $('#manualVerifyPhotoImg').attr('src', '');
1342
    $('#manualVerifyPhotoPreview').hide();
1343
    $('#manualVerifyGeoModal').modal('show');
1344
});
1345
 
1346
// Local thumbnail preview as soon as the user picks a file (no upload yet —
1347
// upload happens on Save so we don't orphan documents on cancel).
1348
$(document).on('change', '#manualVerifyPhoto', function () {
1349
    var f = this.files && this.files[0];
1350
    if (!f) {
1351
        $('#manualVerifyPhotoPreview').hide();
1352
        return;
1353
    }
1354
    var reader = new FileReader();
1355
    reader.onload = function (ev) {
1356
        $('#manualVerifyPhotoImg').attr('src', ev.target.result);
1357
        $('#manualVerifyPhotoPreview').show();
1358
    };
1359
    reader.readAsDataURL(f);
1360
});
1361
 
1362
// Address -> coords via server (uses existing GeocodingService).
1363
// On success, fills the lat/lng box and renders the map preview.
1364
$(document).on('click', '#manualVerifyGeocodeBtn', function () {
1365
    var addr = ($('#manualVerifyAddress').val() || '').trim();
1366
    if (!addr) {
1367
        $('#manualVerifyErr').text('Enter an address first.').show();
1368
        return;
1369
    }
1370
    $('#manualVerifyErr').hide();
1371
    var btn = $(this);
1372
    btn.prop('disabled', true).text('Finding...');
1373
    $.ajax({
1374
        url: context + '/lead-geo/geocode-address',
1375
        type: 'POST',
1376
        data: {address: addr},
1377
        success: function (resp) {
1378
            btn.prop('disabled', false).text('Find on map');
1379
            var r = resp && resp.response ? resp.response : resp;
1380
            if (!r || !r.success) {
1381
                $('#manualVerifyErr').text((r && r.message) || 'Could not geocode that address.').show();
1382
                return;
1383
            }
1384
            $('#manualVerifyLatLng').val(r.latitude + ',' + r.longitude);
1385
            manualVerifyShowMap(r.latitude, r.longitude);
1386
        },
1387
        error: function () {
1388
            btn.prop('disabled', false).text('Find on map');
1389
            $('#manualVerifyErr').text('Geocode request failed. Try again.').show();
1390
        }
1391
    });
1392
});
1393
 
1394
// "Show on map" — re-render the iframe from whatever is in the lat/lng input.
1395
// Useful after the user nudges the coords manually.
1396
$(document).on('click', '#manualVerifyPreviewBtn', function () {
1397
    var parsed = parseLatLngInput($('#manualVerifyLatLng').val());
1398
    if (!parsed) {
1399
        $('#manualVerifyErr').text('Enter latitude,longitude first.').show();
1400
        return;
1401
    }
1402
    $('#manualVerifyErr').hide();
1403
    manualVerifyShowMap(parsed.lat, parsed.lng);
1404
});
1405
 
1406
$(document).on('click', '#manualVerifySaveBtn', function () {
1407
    var lid = $('#manualVerifyLeadId').val();
1408
    var raw = $('#manualVerifyLatLng').val();
1409
    var remark = $('#manualVerifyRemark').val() || '';
1410
    var parsed = parseLatLngInput(raw);
1411
    if (!parsed) {
1412
        $('#manualVerifyErr').text('Could not read latitude/longitude. Paste like 28.6139,77.2090').show();
1413
        return;
1414
    }
1415
    if (parsed.lat < -90 || parsed.lat > 90 || parsed.lng < -180 || parsed.lng > 180
1416
        || (parsed.lat === 0 && parsed.lng === 0)) {
1417
        $('#manualVerifyErr').text('Latitude/longitude out of range.').show();
1418
        return;
1419
    }
1420
    var fileInput = document.getElementById('manualVerifyPhoto');
1421
    var pickedFile = fileInput && fileInput.files && fileInput.files[0];
1422
    if (!pickedFile) {
1423
        $('#manualVerifyErr').text('Please attach a store-board photo to verify.').show();
1424
        return;
1425
    }
1426
    $('#manualVerifyErr').hide();
1427
    var btn = $('#manualVerifySaveBtn');
1428
    btn.prop('disabled', true).text('Verifying...');
1429
 
1430
    function callVerify(docId) {
1431
        $.ajax({
1432
            url: context + '/lead-geo/manual-verify',
1433
            type: 'POST',
1434
            data: {
1435
                leadId: lid,
1436
                latitude: parsed.lat,
1437
                longitude: parsed.lng,
1438
                remark: remark,
1439
                imageDocumentId: docId || 0
1440
            },
1441
            success: function () {
1442
                btn.prop('disabled', false).text('Save & Verify');
1443
                $('#manualVerifyGeoModal').modal('hide');
1444
                // Replace the cell of this lead row with the Verified badge so
1445
                // the user sees the result without reloading the whole list.
1446
                var $cell = $('.verifyGeoManual[data-leadid="' + lid + '"]').closest('td');
1447
                if ($cell.length) {
1448
                    var photoBtn = docId > 0
1449
                        ? '  <a href="' + context + '/open-attachment?documentId=' + docId + '" target="_blank" class="btn btn-xs btn-default" style="margin-bottom:2px;">View Photo</a>'
1450
                        : '';
1451
                    $cell.html(
1452
                        '<div class="btn-group-vertical" style="width:100%">' +
1453
                        '  <span class="label label-success" style="margin-bottom:4px;">Verified</span>' +
1454
                        '  <a href="https://www.google.com/maps?q=' + parsed.lat + ',' + parsed.lng + '" target="_blank" class="btn btn-xs btn-default" style="margin-bottom:2px;">View Map</a>' +
1455
                        photoBtn +
1456
                        '  <button class="btn btn-xs btn-danger reject-geo" data-leadid="' + lid + '">Revoke</button>' +
1457
                        '</div>'
1458
                    );
1459
                }
1460
            },
1461
            error: function (xhr) {
1462
                btn.prop('disabled', false).text('Save & Verify');
1463
                var msg = 'Failed to verify. Please try again.';
1464
                try {
1465
                    var j = xhr.responseJSON || JSON.parse(xhr.responseText || '{}');
1466
                    if (j && j.response) msg = j.response;
1467
                    else if (j && j.message) msg = j.message;
1468
                } catch (e) {
1469
                }
1470
                $('#manualVerifyErr').text(msg).show();
1471
            }
1472
        });
1473
    }
1474
 
1475
    // Upload first, then verify with the returned document id. Photo is
1476
    // required (gate at the top of the handler), so we always go through this.
1477
    btn.text('Uploading photo...');
1478
    var formData = new FormData();
1479
    formData.append('file', pickedFile, pickedFile.name || 'store-photo.jpg');
1480
    $.ajax({
1481
        url: context + '/lead-geo/upload-image',
1482
        type: 'POST',
1483
        data: formData,
1484
        processData: false,
1485
        contentType: false,
1486
        success: function (resp) {
1487
            var r = resp && resp.response ? resp.response : resp;
1488
            var docId = r && (r.document_id || r.documentId || r.id);
1489
            if (!docId) {
1490
                btn.prop('disabled', false).text('Save & Verify');
1491
                $('#manualVerifyErr').text('Photo upload failed. Try again or remove the photo.').show();
1492
                return;
1493
            }
1494
            btn.text('Verifying...');
1495
            callVerify(docId);
1496
        },
1497
        error: function () {
1498
            btn.prop('disabled', false).text('Save & Verify');
1499
            $('#manualVerifyErr').text('Photo upload failed. Try again or remove the photo.').show();
1500
        }
1501
    });
1502
});
1503
 
36642 ranu 1504
// Geo Review navigation
1505
$(document).on('click', '.geo-review', function () {
1506
    doGetAjaxRequestHandler(context + "/lead-geo/pending-reviews", function (response) {
1507
        $('#main-content').html(response);
1508
    });
1509
});
1510
 
1511
// Visit Approvals navigation
1512
$(document).on('click', '.visit-approvals', function () {
1513
    doGetAjaxRequestHandler(context + "/visit-approvals", function (response) {
1514
        $('#main-content').html(response);
1515
    });
1516
});
1517
 
36650 ranu 1518
// Beat Day View — load inline into dashboard
1519
$(document).on('click', '.beat-plan-dayview', function (e) {
1520
    e.preventDefault();
1521
    doGetAjaxRequestHandler(context + '/beatPlan/dayView', function (response) {
1522
        $('#main-content').html(response);
1523
    });
1524
});
1525
 
36655 ranu 1526
// Base Location manager — load inline into dashboard
1527
$(document).on('click', '.base-location', function (e) {
1528
    e.preventDefault();
1529
    doGetAjaxRequestHandler(context + '/beatPlan/baseLocationPage', function (response) {
1530
        $('#main-content').html(response);
1531
    });
1532
});
1533
 
36740 ranu 1534
// Deferred Partners — load inline into dashboard
1535
$(document).on('click', '.beat-plan-deferred', function (e) {
1536
    e.preventDefault();
1537
    doGetAjaxRequestHandler(context + '/beatPlan/deferredView', function (response) {
1538
        $('#main-content').html(response);
1539
    });
1540
});
1541
 
36642 ranu 1542
// Approve geolocation from lead table
1543
$(document).on('click', '.approve-geo', function (e) {
1544
    e.stopPropagation();
1545
    var lid = $(this).data('leadid');
1546
    if (!confirm('Approve geolocation for Lead #' + lid + '?')) return;
1547
 
1548
    var btn = $(this);
1549
    var cell = btn.closest('td');
1550
 
1551
    doPostAjaxRequestWithParamsHandler(
1552
        context + '/lead-geo/review',
1553
        {leadId: lid, status: 'APPROVED', remark: ''},
1554
        function (response) {
1555
            cell.html('<span class="label label-success">Verified</span>');
1556
        }
1557
    );
1558
});
1559
 
1560
// Reject geolocation from lead table
1561
$(document).on('click', '.reject-geo', function (e) {
1562
    e.stopPropagation();
1563
    var lid = $(this).data('leadid');
1564
    var reason = prompt('Reason for rejection:');
1565
    if (reason === null) return;
1566
 
1567
    var btn = $(this);
1568
    var cell = btn.closest('td');
1569
 
1570
    doPostAjaxRequestWithParamsHandler(
1571
        context + '/lead-geo/review',
1572
        {leadId: lid, status: 'REJECTED', remark: reason},
1573
        function (response) {
1574
            cell.html('<button class="btn btn-xs btn-warning generateGeoLink" data-leadid="' + lid + '">Rejected - Resend</button>');
1575
        }
1576
    );
1577
});
1578