Subversion Repositories SmartDukaan

Rev

Rev 36868 | Rev 37003 | 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;
465
    $(document).on('click', ".editLead", function () {
466
        $('#editLeadData').modal('show');
32464 tejbeer 467
 
35548 aman 468
        $("#remark").val("");
469
        $("#assignTo").val("");
470
        $("#editStatus").val("");
471
        $("#reason").val("");
472
        $("#editCity").val("");
473
        $("#editState").val("");
35769 amit 474
        $("#editSource").val("");
35548 aman 475
        $("#editScheduleTime").hide();
32464 tejbeer 476
 
477
 
35548 aman 478
        localStorage.removeItem("frontph");
479
        localStorage.removeItem("leftShoth");
480
        localStorage.removeItem("rightWallh");
481
        localStorage.removeItem("leftWallh");
482
        localStorage.removeItem("internalMarketh");
32464 tejbeer 483
 
35548 aman 484
        row = $(this).closest("tr");
485
        leadId = $(this).data('leadid');
32464 tejbeer 486
 
35548 aman 487
        doAjaxRequestHandler(
488
            context + "/getLeadDetailByLeadId?leadId=" + leadId,
489
            "GET",
490
            function (response) {
32464 tejbeer 491
 
35548 aman 492
                var data = response.response;
493
                if (!data) return;
494
                console.log(data);
495
                $("#editCity").val(data.city);
496
                $("#editState").val(data.state);
497
                $("input[name='outletName']").val(data.outletName);
498
                $("input[name='counterSize']").val(data.counterSize);
499
            }
500
        );
501
    });
32464 tejbeer 502
 
503
 
35548 aman 504
    $(document).on('click', ".lead-edit-request",
505
        function () {
32464 tejbeer 506
 
36761 ranu 507
            // Gate the assign/status submit on approved geo. Modal stays open so the
508
            // user can still work the other sub-forms (lead detail, etc.).
509
            var clickedBtn = $(this);
36789 ranu 510
            // notInterested is a close-out — no geo / no beat / no assignee
511
            // needed. Skip the geo gate and submit straight through with just
512
            // the activity (status + reason + remark).
513
            var currentStatus = $('#editStatus').val();
514
            if (currentStatus === 'notInterested') {
515
                submitLeadEdit();
516
                return;
517
            }
36792 ranu 518
            // Non-sales assignees (BGC / other internal hand-offs) don't need
519
            // geo or a beat-day — the lead just routes to their queue. Skip the
520
            // geo gate and submit straight through, same as the legacy flow.
521
            var assigneeId = parseInt($('#assignTo').val(), 10);
522
            var isSalesAssignee = !isNaN(assigneeId)
523
                && typeof salesUserIds !== 'undefined'
524
                && salesUserIds.indexOf(assigneeId) !== -1;
525
            if (!isSalesAssignee) {
526
                submitLeadEdit();
527
                return;
528
            }
36761 ranu 529
            if (clickedBtn.data('geoChecking')) return;
530
            clickedBtn.data('geoChecking', true);
531
            doAjaxRequestHandler(
532
                context + "/lead-geo/check/" + leadId,
533
                "GET",
534
                function (response) {
535
                    clickedBtn.removeData('geoChecking');
536
                    var hasGeo = response && response.response && response.response.hasApprovedGeo;
537
                    if (!hasGeo) {
538
                        alert('Live geo-location for this lead has not been approved yet. Please approve the geo-location before assigning / updating status.');
539
                        return;
540
                    }
541
                    submitLeadEdit();
542
                }
543
            );
544
        });
25980 tejbeer 545
 
36761 ranu 546
    function submitLeadEdit() {
547
 
35548 aman 548
            console.log(row);
549
            var remark = $('input[name="remark"]').val();
550
            var assignTo = $("#assignTo").val();
551
            var editStatus = $("#editStatus").val();
552
            var city = $('input[name="editCity"]').val();
553
            var state = $("#editState").val();
554
            var reason = $("#reason").val();
25980 tejbeer 555
 
35769 amit 556
            var startDate = $("#startDate").val();
557
            var endDate = $("#endDate").val();
35548 aman 558
            var leadStatus = $("#statusFilter").val();
559
            var color = $("#colorFilter").val();
560
            var communicationType = $("#communicationType").val();
29640 tejbeer 561
 
35548 aman 562
            var conversionprobability = $("#conversionprobability").val();
35769 amit 563
            var editSource = $("#editSource").val();
29640 tejbeer 564
 
35548 aman 565
            console.log(conversionprobability)
29640 tejbeer 566
 
31473 tejbeer 567
 
35769 amit 568
            console.log(startDate)
35548 aman 569
            console.log(leadStatus)
31370 tejbeer 570
 
35548 aman 571
            console.log(color)
572
            console.log(reason)
31370 tejbeer 573
 
35548 aman 574
            if (remark === "" && assignTo === "" && editStatus === "") {
575
                alert("All fields is required");
576
                return;
577
            }
31370 tejbeer 578
 
36789 ranu 579
        // For notInterested (close-out) the lead doesn't need an assignee
580
        // — it's just a status + reason + remark write. Only enforce
581
        // assignTo for the other statuses where scheduling matters.
582
        if (assignTo === "" && editStatus !== "notInterested") {
35548 aman 583
                alert("assignTo is required");
584
                return;
585
            }
31409 tejbeer 586
 
35548 aman 587
            if (remark === "") {
588
                alert("Remark is required");
589
                return;
590
            }
31370 tejbeer 591
 
592
 
35548 aman 593
            if (editStatus === "") {
594
                alert("status is required");
595
                return;
596
            }
31370 tejbeer 597
 
35548 aman 598
            if (editStatus === "notInterested") {
36789 ranu 599
                if (reason == null || reason === "") {
35548 aman 600
                    alert("Reason  is required");
601
                    return;
602
                }
603
            }
604
            var leadActivityData = {}
605
            leadActivityData['id'] = leadId;
606
            leadActivityData['remark'] = remark;
607
            leadActivityData['assignTo'] = assignTo
608
            leadActivityData['status'] = editStatus
609
            leadActivityData['reason'] = reason
36741 ranu 610
            leadActivityData['colorCheck'] = (conversionprobability === "true" || conversionprobability === true)
35548 aman 611
            if (city && city.trim() !== "") {
612
                leadActivityData.city = city;
613
            }
25980 tejbeer 614
 
35548 aman 615
            if (state && state.trim() !== "") {
616
                leadActivityData.state = state;
617
            }
29473 manish 618
 
35769 amit 619
            if (editSource && editSource.trim() !== "") {
620
                leadActivityData.source = editSource;
621
            }
29598 tejbeer 622
 
35769 amit 623
 
35548 aman 624
            if (editStatus == "followUp") {
36642 ranu 625
                leadActivityData['communicationType'] = communicationType
36792 ranu 626
                var assigneeIdForBeat = parseInt(assignTo, 10);
627
                var isSalesAssigneeForBeat = !isNaN(assigneeIdForBeat)
628
                    && typeof salesUserIds !== 'undefined'
629
                    && salesUserIds.indexOf(assigneeIdForBeat) !== -1;
36741 ranu 630
                var beatVal = $('#beatDate').val();
36792 ranu 631
                // Beat-day gate only applies to sales assignees. Non-sales
632
                // (BGC / other) hand-offs are just routed to the user's queue
633
                // without a beat attachment — same as the legacy flow.
634
                if (isSalesAssigneeForBeat) {
635
                    if (!beatVal) {
636
                        var hasBadges = $('#beatBadges .beat-badge').length > 0;
637
                        if (!hasBadges) {
638
                            alert('No upcoming beat is available for this assignee. Cannot schedule the lead until they have a beat.');
639
                        } else {
640
                            alert('Please select a beat date for the assignee before submitting.');
641
                        }
642
                        return;
36761 ranu 643
                    }
36792 ranu 644
                    var beatDate = beatVal.split('|')[0];
645
                    leadActivityData['scheldule'] = beatDate + 'T12:00:00';
646
                    leadActivityData['beatSelection'] = beatVal;
36642 ranu 647
                }
35548 aman 648
            }
29598 tejbeer 649
 
35548 aman 650
            console.log(leadActivityData);
651
            if (confirm("Are you sure you want to add lead!") == true) {
652
                doPostAjaxRequestWithJsonHandler(context + "/editLead", JSON.stringify(leadActivityData), function (response) {
653
                    console.log(response);
654
                    $('#editLeadData').modal('hide');
655
                    $('.modal-backdrop').remove();
656
                    row.html(response);
657
                });
658
            }
29598 tejbeer 659
 
36761 ranu 660
    }
32477 tejbeer 661
 
662
 
35548 aman 663
    $(document).on('click', ".show-partner-health",
664
        function () {
29598 tejbeer 665
 
35548 aman 666
            var email = $("#authUserFilter").val();
25980 tejbeer 667
 
35548 aman 668
            console.log(email)
669
            doGetAjaxRequestHandler(context + "/partnerHealth?email="
670
                + email, function (response) {
671
                console.log(response)
672
                $('#' + 'main-content').html(response);
25980 tejbeer 673
 
35548 aman 674
            });
675
        });
25980 tejbeer 676
 
677
 
35548 aman 678
    $(document).on('click', ".lead-detail-entry",
679
        function () {
28200 tejbeer 680
 
35548 aman 681
            console.log("hello");
682
            var outletName = $('input[name="outletName"]').val();
683
            var counterSize = $('input[name="counterSize"]').val();
684
            var table = document.getElementById('editbrandtable');
685
            var brandValueJson = [];
686
            var leadBrands;
25980 tejbeer 687
 
35548 aman 688
            if (outletName === "") {
689
                alert("Outlet Name is required");
690
                return;
691
            }
29598 tejbeer 692
 
35548 aman 693
            if (counterSize === "") {
694
                alert("Counter Size is required");
695
                return;
696
            }
32471 tejbeer 697
 
35548 aman 698
            if (localStorage.getItem("frontph") == "undefined" && localStorage.getItem("frontph") == null) {
699
                alert("Front Document is required");
700
                return;
701
            }
31249 tejbeer 702
 
35548 aman 703
            if (localStorage.getItem("internalMarketh") == "undefined" || localStorage.getItem("internalMarketh") == null) {
704
                alert("Front With Market Document is required");
705
                return;
706
            }
25980 tejbeer 707
 
35548 aman 708
            if (localStorage.getItem("leftShoth") == "undefined" || localStorage.getItem("leftShoth") == null) {
709
                alert("Internal Left Shot Document is required");
710
                return;
711
            }
27605 tejbeer 712
 
35548 aman 713
            if (localStorage.getItem("leftWallh") == "undefined" || localStorage.getItem("leftWallh") == null) {
714
                alert("Internal Left Wall Document is required");
715
                return;
716
            }
27605 tejbeer 717
 
30185 tejbeer 718
 
35548 aman 719
            if (localStorage.getItem("rightWallh") == "undefined" || localStorage.getItem("rightWallh") == null) {
720
                alert("Internal Right Wall Document is required");
721
                return;
722
            }
30185 tejbeer 723
 
724
 
35548 aman 725
            for (i = 1; i < table.rows.length; i++) {
30185 tejbeer 726
 
35548 aman 727
                var objCells = table.rows[i].cells;
30185 tejbeer 728
 
35548 aman 729
                leadBrands = {
730
                    brand: objCells[0].innerText,
731
                    value: objCells[1].getElementsByTagName('input')[0].value
732
                }
733
                brandValueJson.push(leadBrands);
734
            }
30185 tejbeer 735
 
30416 tejbeer 736
 
35548 aman 737
            var leadDetailObject = {};
31402 tejbeer 738
 
35548 aman 739
            leadDetailObject['leadId'] = leadId;
30416 tejbeer 740
 
741
 
35548 aman 742
            leadDetailObject['outletName'] = outletName;
31370 tejbeer 743
 
35548 aman 744
            leadDetailObject['counterSize'] = counterSize;
31370 tejbeer 745
 
35548 aman 746
            leadDetailObject['leadBrands'] = brandValueJson;
31370 tejbeer 747
 
31402 tejbeer 748
 
35548 aman 749
            console.log(localStorage.getItem("frontp"));
31402 tejbeer 750
 
751
 
35548 aman 752
            leadDetailObject['frontp'] = localStorage
753
                .getItem("frontph");
31402 tejbeer 754
 
755
 
35548 aman 756
            leadDetailObject['frontWithMarket'] = localStorage
757
                .getItem("internalMarketh");
31370 tejbeer 758
 
759
 
35548 aman 760
            leadDetailObject['internalLongShot'] = localStorage
761
                .getItem("leftShoth");
31370 tejbeer 762
 
763
 
35548 aman 764
            leadDetailObject['internalLeftWall'] = localStorage
765
                .getItem("leftWallh");
31370 tejbeer 766
 
767
 
35548 aman 768
            leadDetailObject['internalRightWall'] = localStorage
769
                .getItem("rightWallh");
31370 tejbeer 770
 
35548 aman 771
            console.log(leadDetailObject);
31370 tejbeer 772
 
35548 aman 773
            if (confirm("Are you sure you want to add lead detail!") == true) {
774
                doPostAjaxRequestWithJsonHandler(context + "/leadDetail", JSON.stringify(leadDetailObject), function (response) {
775
                    console.log(response);
776
                    if (response == 'true') {
777
                        alert("Submit Successfully");
778
                    }
31370 tejbeer 779
 
35548 aman 780
                });
781
            }
31370 tejbeer 782
 
35548 aman 783
        });
31370 tejbeer 784
 
785
 
35548 aman 786
    $(document).on('change', '.frontp',
787
        function () {
31370 tejbeer 788
 
35548 aman 789
            if (confirm('Document has been selected, Do you want to upload ?')) {
31370 tejbeer 790
 
35548 aman 791
                var documentId = uploadImage(this, "frontph");
31370 tejbeer 792
 
793
 
35548 aman 794
            } else {
31370 tejbeer 795
 
35548 aman 796
            }
797
        });
31456 tejbeer 798
 
35548 aman 799
    $(document).on('change', '.internalMarket',
800
        function () {
31456 tejbeer 801
 
35548 aman 802
            if (confirm('Document has been selected, Do you want to upload ?')) {
31456 tejbeer 803
 
35548 aman 804
                var documentId = uploadImage(this, "internalMarketh");
31456 tejbeer 805
 
35548 aman 806
            } else {
31456 tejbeer 807
 
35548 aman 808
            }
809
        });
31370 tejbeer 810
 
35548 aman 811
    $(document).on('change', '.leftShot',
31370 tejbeer 812
 
35548 aman 813
        function () {
814
            if (confirm('Document has been selected, Do you want to upload ?')) {
815
                var documentId = uploadImage(this, "leftShoth");
816
            } else {
31370 tejbeer 817
 
35548 aman 818
            }
819
        });
31370 tejbeer 820
 
35548 aman 821
    $(document).on('change', '.leftWall',
822
        function () {
823
            if (confirm('Document has been selected, Do you want to upload ?')) {
824
                var documentId = uploadImage(this, "leftWallh");
825
            } else {
31370 tejbeer 826
 
35548 aman 827
            }
828
        });
31370 tejbeer 829
 
35548 aman 830
    $(document).on('change', '.rightWall',
831
        function () {
832
            if (confirm('Document has been selected, Do you want to upload ?')) {
833
                var documentId = uploadImage(this, "rightWallh");
834
            } else {
835
            }
836
        });
31370 tejbeer 837
 
838
 
25980 tejbeer 839
});
840
 
31404 tejbeer 841
function uploadImage(fileSelector, attrName) {
35548 aman 842
    var documentId;
843
    if (fileSelector != undefined
844
        && fileSelector.files[0] != undefined) {
845
        var url = context
846
            + '/document-upload';
31370 tejbeer 847
 
35548 aman 848
        console.log(url);
849
        var file = fileSelector.files[0];
31370 tejbeer 850
 
35548 aman 851
        console.log(file)
852
        doAjaxUploadRequestHandler(
853
            url,
854
            'POST',
855
            file,
856
            function (response) {
857
                console.log(response)
858
                documentId = response.response.document_id;
859
                console
860
                    .log("documentId : "
861
                        + documentId);
31370 tejbeer 862
 
863
 
35548 aman 864
                localStorage
865
                    .setItem(
866
                        attrName,
867
                        documentId);
31402 tejbeer 868
 
35548 aman 869
            });
870
        return documentId;
871
    }
31370 tejbeer 872
 
873
}
874
 
875
 
25980 tejbeer 876
function loadLead(domId) {
35548 aman 877
    doGetAjaxRequestHandler(context + "/getOpenLead", function (response) {
878
        $('#' + domId).html(response);
879
    });
25980 tejbeer 880
}
881
 
25988 tejbeer 882
function loadClosedLead(domId, searchTerm) {
35548 aman 883
    doGetAjaxRequestHandler(context + "/getClosedLead", function (response) {
884
        $('#' + domId).html(response);
885
    })
25988 tejbeer 886
}
887
 
25980 tejbeer 888
function statusAction() {
35548 aman 889
    var val = $('#status').val();
890
    if (val == "followUp") {
891
        $("#scheduleTime").show();
892
    } else {
893
        $("#scheduleTime").hide();
894
    }
25980 tejbeer 895
 
896
}
27605 tejbeer 897
 
898
 
899
function editStatusAction() {
35548 aman 900
    var val = $('#editStatus').val();
901
    if (val == "followUp") {
36642 ranu 902
        // Show communication type and schedule date
903
        $("#communicationTypeSection").show();
35548 aman 904
        $("#editScheduleTime").show();
36642 ranu 905
        $("#beatDateSelection").hide();
906
 
36761 ranu 907
        // Reset communication type only; preserve the assignee the user picked.
36642 ranu 908
        $('#communicationType').val('');
909
        $('#assignTo option').show();
910
 
911
        // Check if lead has approved geolocation to decide VISIT option
912
        doAjaxRequestHandler(context + "/lead-geo/check/" + leadId, "GET", function (response) {
913
            var hasGeo = response.response.hasApprovedGeo;
914
            var commDropdown = $('#communicationType');
915
            commDropdown.empty();
916
            commDropdown.append('<option value="" disabled selected>Communication Type</option>');
917
            commDropdown.append('<option value="TELEPHONIC">TELEPHONIC</option>');
918
            if (hasGeo) {
919
                commDropdown.append('<option value="VISIT">VISIT</option>');
920
            }
921
        });
35548 aman 922
    } else {
36642 ranu 923
        $("#communicationTypeSection").hide();
35548 aman 924
        $("#editScheduleTime").hide();
36642 ranu 925
        $("#beatDateSelection").hide();
926
        $('#assignTo option').show();
35548 aman 927
    }
27605 tejbeer 928
 
929
}
930
 
25988 tejbeer 931
function loadLeadSearchInfo(search_text) {
35548 aman 932
    loadSearchLead("main-content", search_text);
25988 tejbeer 933
}
934
 
30185 tejbeer 935
function loadTeamCommitment(domId) {
35548 aman 936
    doGetAjaxRequestHandler(context + "/teamCommitment",
937
        function (response) {
938
            $('#' + domId).html(response);
939
        });
30185 tejbeer 940
}
941
 
31370 tejbeer 942
function loadLeadDetail(domId) {
35548 aman 943
    doGetAjaxRequestHandler(context + "/getLeadDetail",
944
        function (response) {
945
            $('#' + domId).html(response);
946
        });
31370 tejbeer 947
}
948
 
30416 tejbeer 949
function loadPartnerHealth(domId) {
35548 aman 950
    doGetAjaxRequestHandler(context + "/partnerHealth",
951
        function (response) {
952
            $('#' + domId).html(response);
953
        });
30416 tejbeer 954
}
955
 
25988 tejbeer 956
function loadSearchLead(domId, search_text) {
35548 aman 957
    doGetAjaxRequestHandler(context + "/searchLeads?searchTerm=" + search_text,
958
        function (response) {
959
            $('#' + domId).html(response);
960
        });
25988 tejbeer 961
}
33917 ranu 962
 
963
$(document).on('click', ".arr-button-mk",
35548 aman 964
    function () {
965
        var startDate = $('.arr-start_date').val();
966
        doGetAjaxRequestHandler(context + "/rbmTodayArr?startDate=" + startDate, function (response) {
967
            $('#main-content').html(response);
33917 ranu 968
 
35548 aman 969
        });
970
    });
33917 ranu 971
 
972
$(document).on('click', ".rbm-today-arr",
35548 aman 973
    function () {
974
        doGetAjaxRequestHandler(context + "/rbmTodayArr", function (response) {
975
            $('#main-content').html(response);
33917 ranu 976
 
35548 aman 977
        });
978
    });
979
$(document).on('click', '.reassign', function () {
980
    $('#bulkReassignFile').val(null);
981
    $('#bulkReassignFile').click();
982
});
983
 
984
$(document).on('change', '#bulkReassignFile', function () {
985
 
986
    if (!confirm("Confirm bulk reassign upload?")) {
987
        return;
988
    }
989
 
990
    var file = this.files[0];
991
    if (!file) {
992
        alert("No file selected");
993
        return;
994
    }
995
 
996
    doAjaxUploadRequestHandler(
997
        context + "/upload-assign-id",
998
        'POST',
999
        file,
1000
        function (response) {
1001
            alert("Bulk reassignment completed");
1002
            loadLead("main-content");
1003
        }
1004
    );
1005
});
1006
 
36642 ranu 1007
// ==================== GEO LOCATION HANDLERS ====================
1008
 
1009
// Communication type change: filter assignTo based on type
1010
$(document).on('change', '#communicationType', function () {
1011
    var val = $(this).val();
1012
    var assignDropdown = $('#assignTo');
1013
 
36741 ranu 1014
    // Reset beat + restore manual date input
36642 ranu 1015
    $('#beatDate').val('');
1016
    $('#beatBadges').empty();
1017
    $("#beatDateSelection").hide();
36741 ranu 1018
    $("#editScheduleTime").show();
36642 ranu 1019
 
1020
    if (val == 'VISIT') {
1021
        // Filter assignTo to sales users only (no BGC)
1022
        if (typeof salesUserIds !== 'undefined') {
1023
            assignDropdown.find('option').each(function () {
1024
                var optVal = parseInt($(this).val());
1025
                if (optVal && salesUserIds.indexOf(optVal) === -1) {
1026
                    $(this).hide();
1027
                } else {
1028
                    $(this).show();
1029
                }
1030
            });
1031
        }
1032
    } else {
1033
        // TELEPHONIC — show all users
1034
        assignDropdown.find('option').show();
1035
    }
36741 ranu 1036
    // Both VISIT and TELEPHONIC offer beat-day slots when an assignee is set
1037
    // (TELEPHONIC just uses the beat date as the call slot; backend won't
1038
    // attach a LeadRoute for it). Non-sales assignees simply get an empty list.
1039
    if (val && assignDropdown.val()) {
1040
        fetchBeatDates();
1041
    }
36642 ranu 1042
});
1043
 
36741 ranu 1044
// Fetch beats when assignTo changes (works for both VISIT and TELEPHONIC)
1045
$(document).on('change', '#assignTo', function () {
36642 ranu 1046
    var commType = $('#communicationType').val();
1047
    var salesAuthId = $('#assignTo').val();
36741 ranu 1048
    if (commType && salesAuthId && leadId) {
36642 ranu 1049
        fetchBeatDates();
36741 ranu 1050
    } else if (!commType) {
36642 ranu 1051
        $("#beatDateSelection").hide();
1052
    }
1053
});
1054
 
1055
function fetchBeatDates() {
1056
    var salesAuthId = $('#assignTo').val();
1057
    if (!salesAuthId || !leadId) return;
1058
 
36792 ranu 1059
    // Beat slots only make sense for sales assignees. BGC / other internal
1060
    // hand-offs skip the entire beat panel (and the visit-request CTA that
1061
    // sits inside it). Mirrors the server-side carve-out in /editLead.
1062
    var assigneeIntId = parseInt(salesAuthId, 10);
1063
    var isSalesAssigneeFetch = !isNaN(assigneeIntId)
1064
        && typeof salesUserIds !== 'undefined'
1065
        && salesUserIds.indexOf(assigneeIntId) !== -1;
1066
    if (!isSalesAssigneeFetch) {
1067
        $('#beatBadges').empty();
1068
        $('#beatDate').val('');
1069
        $('#beatDateSelection').hide();
1070
        return;
1071
    }
1072
 
36642 ranu 1073
    var badgesDiv = $('#beatBadges');
1074
    badgesDiv.html('<span style="color:#999; font-size:12px;">Loading beats...</span>');
1075
    $("#beatDateSelection").show();
1076
    $('#beatDate').val('');
1077
 
1078
    var url = context + "/lead-geo/beat-dates?leadId=" + leadId + "&salesAuthId=" + salesAuthId;
1079
 
1080
    $.ajax({
1081
        url: url,
1082
        method: 'GET',
1083
        success: function (response) {
1084
            var data = response.response || response;
1085
            badgesDiv.empty();
36644 ranu 1086
 
36741 ranu 1087
            // Stores within radius of the lead — show count + top 3 inline.
1088
            var radius = (data && data.radiusKm) ? data.radiusKm : 30;
1089
            var stores = (data && data.nearestStores) || [];
1090
            if (stores.length > 0) {
1091
                var preview = stores.slice(0, 3).map(function (s) {
1092
                    return '<strong>' + s.code + ' - ' + s.name + '</strong> (' + s.distanceKm + ' km)';
1093
                }).join(', ');
1094
                var more = stores.length > 3 ? ' +' + (stores.length - 3) + ' more' : '';
36644 ranu 1095
                badgesDiv.append('<div style="font-size:12px; color:#333; margin-bottom:6px;">' +
36741 ranu 1096
                    stores.length + ' partner store(s) within ' + radius + ' km of this lead: ' +
1097
                    preview + more + '</div>');
36644 ranu 1098
            }
1099
 
36741 ranu 1100
            // All upcoming beat-dates for the assignee that touch any nearby store.
36642 ranu 1101
            if (data && data.beats && data.beats.length > 0) {
36644 ranu 1102
                badgesDiv.append('<div style="font-weight:bold; font-size:11px; color:#666; margin-bottom:4px;">Available Slots (near this lead):</div>');
36741 ranu 1103
                var beats = data.beats;
36642 ranu 1104
                for (var i = 0; i < beats.length; i++) {
1105
                    var beat = beats[i];
36644 ranu 1106
                    var nearTxt = beat.nearStore ? ' &middot; near ' + beat.nearStore : '';
36642 ranu 1107
                    var badge = $('<span class="beat-badge" style="' +
1108
                        'display:inline-block; background:#337ab7; color:#fff; padding:6px 12px; ' +
1109
                        'margin:4px 6px 4px 0; border-radius:16px; cursor:pointer; font-size:12px; ' +
1110
                        'border:2px solid #337ab7; transition:all 0.2s;">' +
36644 ranu 1111
                        beat.planDate + ' &middot; ' + beat.beatName + ' (' + beat.stops + ' stops)' + nearTxt +
36642 ranu 1112
                        '</span>');
1113
                    badge.data('value', beat.planDate + '|' + beat.beatName + '|' + beat.planGroupId);
1114
                    badgesDiv.append(badge);
1115
                }
1116
            } else {
36787 ranu 1117
                // No beat-days available for this assignee. Surface a CTA so the
1118
                // user can fire a visit request to the assignee's hierarchy instead
1119
                // of being stuck. The pre-existing 'beats > 0' branch above is
1120
                // untouched — this only fires for the empty-beats case.
1121
                var nearestId = (stores.length > 0 && stores[0].storeId) ? stores[0].storeId : '';
1122
                badgesDiv.append(
1123
                    '<div style="background:#fff8e1; border:1px solid #f0e0a0; border-radius:6px; padding:8px 10px; margin-top:4px;">'
1124
                    + '<div style="font-size:12px; color:#7c5a00; margin-bottom:6px;">'
1125
                    + 'No upcoming beat is available for this assignee.'
1126
                    + '</div>'
1127
                    + '<div style="display:flex; gap:8px; align-items:center;">'
1128
                    + '<label style="font-size:11px; color:#666; margin:0;">Preferred date (optional):</label>'
1129
                    + '<input type="date" id="vrPreferredDate" class="input-sm" style="font-size:12px; padding:3px 6px;">'
1130
                    + '<button type="button" id="vrSendBtn" class="btn btn-warning btn-sm" '
1131
                    + 'data-nearest="' + nearestId + '" style="font-size:12px;">Send Visit Request</button>'
1132
                    + '</div>'
1133
                    + '<div style="font-size:11px; color:#888; margin-top:6px;">'
1134
                    + '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.'
1135
                    + '</div>'
1136
                    + '</div>');
36642 ranu 1137
            }
1138
        },
1139
        error: function () {
1140
            badgesDiv.html('<span style="color:#d9534f; font-size:12px;">Error loading beats</span>');
1141
        }
1142
    });
1143
}
1144
 
36787 ranu 1145
// Send Visit Request when no beats are available for the chosen assignee.
1146
// Posts to /visitRequest/create. Existing beat-pick + Submit flow is unchanged.
1147
$(document).on('click', '#vrSendBtn', function () {
1148
    var $btn = $(this);
1149
    var assigneeAuthId = parseInt($('#assignTo').val());
1150
    var commType = $('#communicationType').val() || null;
1151
    var nearestStoreId = parseInt($btn.data('nearest'));
1152
    var preferred = $('#vrPreferredDate').val() || null;
1153
    if (!leadId || !assigneeAuthId) {
1154
        alert('Pick an assignee first.');
1155
        return;
1156
    }
1157
    $btn.prop('disabled', true).text('Sending...');
1158
    var payload = {
1159
        leadId: leadId,
1160
        assigneeAuthId: assigneeAuthId,
1161
        communicationType: commType,
1162
        reason: 'No upcoming beats for assignee'
1163
    };
1164
    if (!isNaN(nearestStoreId) && nearestStoreId > 0) payload.nearestStoreId = nearestStoreId;
1165
    if (preferred) payload.requestedDate = preferred;
1166
 
1167
    doPostAjaxRequestWithJsonHandler(context + '/visitRequest/create', JSON.stringify(payload),
1168
        function (response) {
1169
            $btn.prop('disabled', false).text('Send Visit Request');
1170
            var data = (response && response.response) || response || {};
1171
            if (data && data.id) {
1172
                alert('Visit request sent. The assignee\'s manager has been notified.');
1173
                $('#editLeadData').modal('hide');
1174
                $('.modal-backdrop').remove();
1175
            } else {
1176
                var msg = (data && data.message) || (data && data.error) || 'Could not send request.';
1177
                alert(msg);
1178
            }
1179
        });
1180
});
1181
 
36741 ranu 1182
// Click on beat badge to select it. A picked beat becomes the schedule
1183
// source — the manual date input is hidden (not needed when scheduling by beat).
36642 ranu 1184
$(document).on('click', '.beat-badge', function () {
1185
    $('.beat-badge').css({'background': '#337ab7', 'border-color': '#337ab7'});
1186
    $(this).css({'background': '#1a5276', 'border-color': '#f39c12', 'border-width': '2px'});
1187
    $('#beatDate').val($(this).data('value'));
36741 ranu 1188
    $("#editScheduleTime").hide();
36642 ranu 1189
});
1190
 
1191
// Generate Geo Link for lead
1192
$(document).on('click', '.generateGeoLink', function (e) {
1193
    e.stopPropagation();
1194
    var lid = $(this).data('leadid');
1195
    doAjaxRequestHandler(context + "/lead-geo/generate-link?leadId=" + lid, "GET", function (response) {
1196
        var url = response.response;
1197
        if (navigator.clipboard) {
1198
            navigator.clipboard.writeText(url).then(function () {
1199
                alert("Link copied to clipboard:\n" + url);
1200
            });
1201
        } else {
1202
            prompt("Share this link with the prospect:", url);
1203
        }
1204
    });
1205
});
1206
 
36868 ranu 1207
// Manual geo verification — for cases where the prospect refused to tap the
1208
// verification link. Team-member confirms lat/lng over phone (or pastes a
1209
// Maps URL the prospect shared) and writes it APPROVED directly.
1210
function ensureManualVerifyModal() {
1211
    if ($('#manualVerifyGeoModal').length) return;
1212
    var html =
1213
        '<div id="manualVerifyGeoModal" class="modal" role="dialog" tabindex="-1">' +
1214
        '  <div class="modal-dialog modal-lg">' +
1215
        '    <div class="modal-content">' +
1216
        '      <div class="modal-header">' +
1217
        '        <button type="button" class="close" data-dismiss="modal">&times;</button>' +
1218
        '        <h4 class="modal-title">Verify Lead Location Manually</h4>' +
1219
        '      </div>' +
1220
        '      <div class="modal-body" style="max-height:75vh;overflow-y:auto;">' +
1221
        '        <input type="hidden" id="manualVerifyLeadId">' +
1222
        '        <div class="form-group">' +
1223
        '          <label>Address <small class="text-muted">(include city, state, pincode for best result)</small></label>' +
1224
        '          <div class="input-group">' +
1225
        '            <input type="text" class="form-control" id="manualVerifyAddress" placeholder="e.g. Shop 12, Sector 18, Noida, UP, 201301">' +
1226
        '            <span class="input-group-btn">' +
1227
        '              <button type="button" class="btn btn-default" id="manualVerifyGeocodeBtn">Find on map</button>' +
1228
        '            </span>' +
1229
        '          </div>' +
1230
        '        </div>' +
1231
        '        <div class="form-group">' +
1232
        '          <label>Latitude, Longitude</label>' +
1233
        '          <div class="input-group">' +
1234
        '            <input type="text" class="form-control" id="manualVerifyLatLng" placeholder="28.6139,77.2090">' +
1235
        '            <span class="input-group-btn">' +
1236
        '              <button type="button" class="btn btn-default" id="manualVerifyPreviewBtn">Show on map</button>' +
1237
        '            </span>' +
1238
        '          </div>' +
1239
        '          <small class="text-muted">You can also paste a Google Maps URL containing coords.</small>' +
1240
        '        </div>' +
1241
        '        <div class="form-group" id="manualVerifyMapWrap" style="display:none;">' +
1242
        '          <label>Map preview <small class="text-muted">(confirm the pin is right)</small></label>' +
1243
        '          <div style="border:1px solid #ddd;border-radius:3px;overflow:hidden;">' +
1244
        '            <iframe id="manualVerifyMapFrame" width="100%" height="260" frameborder="0" style="border:0;" allowfullscreen></iframe>' +
1245
        '          </div>' +
1246
        '          <small><a href="#" id="manualVerifyOpenMap" target="_blank">Open in Google Maps</a></small>' +
1247
        '        </div>' +
1248
        '        <div class="form-group">' +
1249
        '          <label>Store-board photo <span class="text-danger">*</span> <small class="text-muted">(required &mdash; proves the verification)</small></label>' +
1250
        '          <input type="file" id="manualVerifyPhoto" accept="image/jpeg,image/png" required>' +
1251
        '          <div id="manualVerifyPhotoPreview" style="margin-top:6px;display:none;">' +
1252
        '            <img id="manualVerifyPhotoImg" src="" style="max-height:120px;border:1px solid #ddd;border-radius:3px;padding:2px;">' +
1253
        '          </div>' +
1254
        '        </div>' +
1255
        '        <div class="form-group">' +
1256
        '          <label>Remark <small class="text-muted">(optional)</small></label>' +
1257
        '          <input type="text" class="form-control" id="manualVerifyRemark" placeholder="e.g. Confirmed on call with prospect">' +
1258
        '        </div>' +
1259
        '        <div id="manualVerifyErr" class="text-danger" style="display:none;"></div>' +
1260
        '      </div>' +
1261
        '      <div class="modal-footer">' +
1262
        '        <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>' +
1263
        '        <button type="button" class="btn btn-success" id="manualVerifySaveBtn">Save &amp; Verify</button>' +
1264
        '      </div>' +
1265
        '    </div>' +
1266
        '  </div>' +
1267
        '</div>';
1268
    $('body').append(html);
1269
}
1270
 
1271
function manualVerifyShowMap(lat, lng) {
1272
    var src = 'https://www.google.com/maps?q=' + lat + ',' + lng + '&z=17&output=embed';
1273
    $('#manualVerifyMapFrame').attr('src', src);
1274
    $('#manualVerifyOpenMap').attr('href', 'https://www.google.com/maps?q=' + lat + ',' + lng);
1275
    $('#manualVerifyMapWrap').show();
1276
}
1277
 
1278
// Parses raw "lat,lng" or a Google Maps URL containing the coords.
1279
// Maps formats covered: /@lat,lng, /maps?q=lat,lng, ?ll=lat,lng, ?destination=lat,lng.
1280
function parseLatLngInput(raw) {
1281
    if (!raw) return null;
1282
    var s = String(raw).trim();
1283
    // Strip any leading "lat:" / "lng:" tokens
1284
    var direct = s.match(/(-?\d{1,3}\.\d+)\s*,\s*(-?\d{1,3}\.\d+)/);
1285
    if (direct) return {lat: parseFloat(direct[1]), lng: parseFloat(direct[2])};
1286
    return null;
1287
}
1288
 
1289
$(document).on('click', '.verifyGeoManual', function (e) {
1290
    e.stopPropagation();
1291
    var lid = $(this).data('leadid');
1292
    ensureManualVerifyModal();
1293
    $('#manualVerifyLeadId').val(lid);
1294
    $('#manualVerifyAddress').val('');
1295
    $('#manualVerifyLatLng').val('');
1296
    $('#manualVerifyRemark').val('');
1297
    $('#manualVerifyErr').hide().text('');
1298
    $('#manualVerifyMapWrap').hide();
1299
    $('#manualVerifyMapFrame').attr('src', '');
1300
    $('#manualVerifyPhoto').val('');
1301
    $('#manualVerifyPhotoImg').attr('src', '');
1302
    $('#manualVerifyPhotoPreview').hide();
1303
    $('#manualVerifyGeoModal').modal('show');
1304
});
1305
 
1306
// Local thumbnail preview as soon as the user picks a file (no upload yet —
1307
// upload happens on Save so we don't orphan documents on cancel).
1308
$(document).on('change', '#manualVerifyPhoto', function () {
1309
    var f = this.files && this.files[0];
1310
    if (!f) {
1311
        $('#manualVerifyPhotoPreview').hide();
1312
        return;
1313
    }
1314
    var reader = new FileReader();
1315
    reader.onload = function (ev) {
1316
        $('#manualVerifyPhotoImg').attr('src', ev.target.result);
1317
        $('#manualVerifyPhotoPreview').show();
1318
    };
1319
    reader.readAsDataURL(f);
1320
});
1321
 
1322
// Address -> coords via server (uses existing GeocodingService).
1323
// On success, fills the lat/lng box and renders the map preview.
1324
$(document).on('click', '#manualVerifyGeocodeBtn', function () {
1325
    var addr = ($('#manualVerifyAddress').val() || '').trim();
1326
    if (!addr) {
1327
        $('#manualVerifyErr').text('Enter an address first.').show();
1328
        return;
1329
    }
1330
    $('#manualVerifyErr').hide();
1331
    var btn = $(this);
1332
    btn.prop('disabled', true).text('Finding...');
1333
    $.ajax({
1334
        url: context + '/lead-geo/geocode-address',
1335
        type: 'POST',
1336
        data: {address: addr},
1337
        success: function (resp) {
1338
            btn.prop('disabled', false).text('Find on map');
1339
            var r = resp && resp.response ? resp.response : resp;
1340
            if (!r || !r.success) {
1341
                $('#manualVerifyErr').text((r && r.message) || 'Could not geocode that address.').show();
1342
                return;
1343
            }
1344
            $('#manualVerifyLatLng').val(r.latitude + ',' + r.longitude);
1345
            manualVerifyShowMap(r.latitude, r.longitude);
1346
        },
1347
        error: function () {
1348
            btn.prop('disabled', false).text('Find on map');
1349
            $('#manualVerifyErr').text('Geocode request failed. Try again.').show();
1350
        }
1351
    });
1352
});
1353
 
1354
// "Show on map" — re-render the iframe from whatever is in the lat/lng input.
1355
// Useful after the user nudges the coords manually.
1356
$(document).on('click', '#manualVerifyPreviewBtn', function () {
1357
    var parsed = parseLatLngInput($('#manualVerifyLatLng').val());
1358
    if (!parsed) {
1359
        $('#manualVerifyErr').text('Enter latitude,longitude first.').show();
1360
        return;
1361
    }
1362
    $('#manualVerifyErr').hide();
1363
    manualVerifyShowMap(parsed.lat, parsed.lng);
1364
});
1365
 
1366
$(document).on('click', '#manualVerifySaveBtn', function () {
1367
    var lid = $('#manualVerifyLeadId').val();
1368
    var raw = $('#manualVerifyLatLng').val();
1369
    var remark = $('#manualVerifyRemark').val() || '';
1370
    var parsed = parseLatLngInput(raw);
1371
    if (!parsed) {
1372
        $('#manualVerifyErr').text('Could not read latitude/longitude. Paste like 28.6139,77.2090').show();
1373
        return;
1374
    }
1375
    if (parsed.lat < -90 || parsed.lat > 90 || parsed.lng < -180 || parsed.lng > 180
1376
        || (parsed.lat === 0 && parsed.lng === 0)) {
1377
        $('#manualVerifyErr').text('Latitude/longitude out of range.').show();
1378
        return;
1379
    }
1380
    var fileInput = document.getElementById('manualVerifyPhoto');
1381
    var pickedFile = fileInput && fileInput.files && fileInput.files[0];
1382
    if (!pickedFile) {
1383
        $('#manualVerifyErr').text('Please attach a store-board photo to verify.').show();
1384
        return;
1385
    }
1386
    $('#manualVerifyErr').hide();
1387
    var btn = $('#manualVerifySaveBtn');
1388
    btn.prop('disabled', true).text('Verifying...');
1389
 
1390
    function callVerify(docId) {
1391
        $.ajax({
1392
            url: context + '/lead-geo/manual-verify',
1393
            type: 'POST',
1394
            data: {
1395
                leadId: lid,
1396
                latitude: parsed.lat,
1397
                longitude: parsed.lng,
1398
                remark: remark,
1399
                imageDocumentId: docId || 0
1400
            },
1401
            success: function () {
1402
                btn.prop('disabled', false).text('Save & Verify');
1403
                $('#manualVerifyGeoModal').modal('hide');
1404
                // Replace the cell of this lead row with the Verified badge so
1405
                // the user sees the result without reloading the whole list.
1406
                var $cell = $('.verifyGeoManual[data-leadid="' + lid + '"]').closest('td');
1407
                if ($cell.length) {
1408
                    var photoBtn = docId > 0
1409
                        ? '  <a href="' + context + '/open-attachment?documentId=' + docId + '" target="_blank" class="btn btn-xs btn-default" style="margin-bottom:2px;">View Photo</a>'
1410
                        : '';
1411
                    $cell.html(
1412
                        '<div class="btn-group-vertical" style="width:100%">' +
1413
                        '  <span class="label label-success" style="margin-bottom:4px;">Verified</span>' +
1414
                        '  <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>' +
1415
                        photoBtn +
1416
                        '  <button class="btn btn-xs btn-danger reject-geo" data-leadid="' + lid + '">Revoke</button>' +
1417
                        '</div>'
1418
                    );
1419
                }
1420
            },
1421
            error: function (xhr) {
1422
                btn.prop('disabled', false).text('Save & Verify');
1423
                var msg = 'Failed to verify. Please try again.';
1424
                try {
1425
                    var j = xhr.responseJSON || JSON.parse(xhr.responseText || '{}');
1426
                    if (j && j.response) msg = j.response;
1427
                    else if (j && j.message) msg = j.message;
1428
                } catch (e) {
1429
                }
1430
                $('#manualVerifyErr').text(msg).show();
1431
            }
1432
        });
1433
    }
1434
 
1435
    // Upload first, then verify with the returned document id. Photo is
1436
    // required (gate at the top of the handler), so we always go through this.
1437
    btn.text('Uploading photo...');
1438
    var formData = new FormData();
1439
    formData.append('file', pickedFile, pickedFile.name || 'store-photo.jpg');
1440
    $.ajax({
1441
        url: context + '/lead-geo/upload-image',
1442
        type: 'POST',
1443
        data: formData,
1444
        processData: false,
1445
        contentType: false,
1446
        success: function (resp) {
1447
            var r = resp && resp.response ? resp.response : resp;
1448
            var docId = r && (r.document_id || r.documentId || r.id);
1449
            if (!docId) {
1450
                btn.prop('disabled', false).text('Save & Verify');
1451
                $('#manualVerifyErr').text('Photo upload failed. Try again or remove the photo.').show();
1452
                return;
1453
            }
1454
            btn.text('Verifying...');
1455
            callVerify(docId);
1456
        },
1457
        error: function () {
1458
            btn.prop('disabled', false).text('Save & Verify');
1459
            $('#manualVerifyErr').text('Photo upload failed. Try again or remove the photo.').show();
1460
        }
1461
    });
1462
});
1463
 
36642 ranu 1464
// Geo Review navigation
1465
$(document).on('click', '.geo-review', function () {
1466
    doGetAjaxRequestHandler(context + "/lead-geo/pending-reviews", function (response) {
1467
        $('#main-content').html(response);
1468
    });
1469
});
1470
 
1471
// Visit Approvals navigation
1472
$(document).on('click', '.visit-approvals', function () {
1473
    doGetAjaxRequestHandler(context + "/visit-approvals", function (response) {
1474
        $('#main-content').html(response);
1475
    });
1476
});
1477
 
36650 ranu 1478
// Beat Day View — load inline into dashboard
1479
$(document).on('click', '.beat-plan-dayview', function (e) {
1480
    e.preventDefault();
1481
    doGetAjaxRequestHandler(context + '/beatPlan/dayView', function (response) {
1482
        $('#main-content').html(response);
1483
    });
1484
});
1485
 
36655 ranu 1486
// Base Location manager — load inline into dashboard
1487
$(document).on('click', '.base-location', function (e) {
1488
    e.preventDefault();
1489
    doGetAjaxRequestHandler(context + '/beatPlan/baseLocationPage', function (response) {
1490
        $('#main-content').html(response);
1491
    });
1492
});
1493
 
36740 ranu 1494
// Deferred Partners — load inline into dashboard
1495
$(document).on('click', '.beat-plan-deferred', function (e) {
1496
    e.preventDefault();
1497
    doGetAjaxRequestHandler(context + '/beatPlan/deferredView', function (response) {
1498
        $('#main-content').html(response);
1499
    });
1500
});
1501
 
36642 ranu 1502
// Approve geolocation from lead table
1503
$(document).on('click', '.approve-geo', function (e) {
1504
    e.stopPropagation();
1505
    var lid = $(this).data('leadid');
1506
    if (!confirm('Approve geolocation for Lead #' + lid + '?')) return;
1507
 
1508
    var btn = $(this);
1509
    var cell = btn.closest('td');
1510
 
1511
    doPostAjaxRequestWithParamsHandler(
1512
        context + '/lead-geo/review',
1513
        {leadId: lid, status: 'APPROVED', remark: ''},
1514
        function (response) {
1515
            cell.html('<span class="label label-success">Verified</span>');
1516
        }
1517
    );
1518
});
1519
 
1520
// Reject geolocation from lead table
1521
$(document).on('click', '.reject-geo', function (e) {
1522
    e.stopPropagation();
1523
    var lid = $(this).data('leadid');
1524
    var reason = prompt('Reason for rejection:');
1525
    if (reason === null) return;
1526
 
1527
    var btn = $(this);
1528
    var cell = btn.closest('td');
1529
 
1530
    doPostAjaxRequestWithParamsHandler(
1531
        context + '/lead-geo/review',
1532
        {leadId: lid, status: 'REJECTED', remark: reason},
1533
        function (response) {
1534
            cell.html('<button class="btn btn-xs btn-warning generateGeoLink" data-leadid="' + lid + '">Rejected - Resend</button>');
1535
        }
1536
    );
1537
});
1538