Subversion Repositories SmartDukaan

Rev

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