Subversion Repositories SmartDukaan

Rev

Rev 36740 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
36740 ranu 1
<section class="wrapper">
2
    <div class="row">
3
        <div class="col-lg-12">
4
            <h3 class="page-header"><i class="icon_calendar"></i> Deferred Partners</h3>
5
            <ol class="breadcrumb">
6
                <li><i class="fa fa-home"></i><a href="${rc.contextPath}/dashboard">Home</a></li>
7
                <li><i class="icon_group"></i> Partner Acquisition</li>
8
                <li><i class="icon_calendar"></i> Deferred Partners</li>
9
            </ol>
10
        </div>
11
    </div>
12
 
13
    <div class="row" style="margin-bottom:10px;">
14
        <div class="col-lg-12" style="display:flex; gap:10px; align-items:center; flex-wrap:wrap;">
36761 ranu 15
            <label style="margin:0;">Date:</label>
16
            <input type="date" id="defDate" class="form-control input-sm" style="width:160px;">
36740 ranu 17
            <button class="btn btn-primary btn-sm" id="defLoad">Load</button>
18
            <span id="defSummary" style="color:#777; font-size:12px; margin-left:10px;"></span>
19
        </div>
20
    </div>
21
 
22
    <div class="row">
23
        <div class="col-lg-12">
24
            <div class="table-responsive">
25
                <table class="table table-bordered table-striped table-hover" id="defTable">
26
                    <thead>
27
                    <tr>
28
                        <th>User</th>
29
                        <th>Date</th>
30
                        <th>Type</th>
31
                        <th>Partner / Agenda</th>
32
                        <th>Reason</th>
33
                        <th>Status</th>
34
                        <th>Next Scheduled</th>
35
                        <th>Action</th>
36
                    </tr>
37
                    </thead>
38
                    <tbody id="defRows">
39
                    <tr>
36761 ranu 40
                        <td colspan="8" style="text-align:center; color:#999;">Pick a date and click Load.</td>
36740 ranu 41
                    </tr>
42
                    </tbody>
43
                </table>
44
            </div>
45
        </div>
46
    </div>
47
</section>
48
 
49
<!-- Reschedule modal -->
50
<!-- Reschedule via the beat-plan calendar window (pick an upcoming beat to drop the item into) -->
51
<div class="modal fade" id="defCalModal" tabindex="-1">
52
    <div class="modal-dialog" style="width:95%; max-width:1300px; margin-top:20px;">
53
        <div class="modal-content">
54
            <div class="modal-header">
55
                <button type="button" class="close" data-dismiss="modal"
56
                        onclick="$('#defCalFrame').attr('src','');">&times;
57
                </button>
58
                <h4 class="modal-title" id="defCalTitle">Reschedule into a Beat</h4>
59
            </div>
60
            <div class="modal-body" style="padding:0;">
61
                <iframe id="defCalFrame" style="width:100%; height:80vh; border:none;"></iframe>
62
            </div>
63
        </div>
64
    </div>
65
</div>
66
 
67
<script>
68
    (function () {
69
        var d = new Date();
70
 
71
        function fmt(x) {
72
            return x.getFullYear() + '-' + ('0' + (x.getMonth() + 1)).slice(-2) + '-' + ('0' + x.getDate()).slice(-2);
73
        }
74
 
36761 ranu 75
        $('#defDate').val(fmt(d));
36740 ranu 76
        loadDeferred();
77
    })();
78
 
79
    $(document).on('click', '#defLoad', function () {
80
        loadDeferred();
81
    });
82
 
83
    function loadDeferred() {
36761 ranu 84
        var d = $('#defDate').val();
85
        if (!d) {
86
            alert('Pick a date');
36740 ranu 87
            return;
88
        }
89
        $('#defRows').html('<tr><td colspan="8" style="text-align:center;">Loading...</td></tr>');
90
        $('#defSummary').text('');
36761 ranu 91
        $.get(context + '/beatPlan/deferred', {startDate: d, endDate: d}).done(function (r) {
36740 ranu 92
            var data = r.response || r;
93
            renderDeferredRows(data.rows || []);
36761 ranu 94
            $('#defSummary').text((data.rows || []).length + ' deferred on ' + data.startDate);
36740 ranu 95
        }).fail(function (xhr) {
96
            $('#defRows').html('<tr><td colspan="8" style="color:#d9534f; text-align:center;">Error: ' + (xhr.responseText || xhr.statusText) + '</td></tr>');
97
        });
98
    }
99
 
100
    function renderDeferredRows(rows) {
101
        if (!rows || rows.length === 0) {
36761 ranu 102
            $('#defRows').html('<tr><td colspan="8" style="text-align:center; color:#999;">No deferred items on this date.</td></tr>');
36740 ranu 103
            return;
104
        }
105
        var html = '';
106
        rows.forEach(function (r) {
107
            // "Auto-covered" = the same partner is on an upcoming beat run. Just a
108
            // hint — the row stays actionable (the next run may be far off, so the
109
            // head can still reschedule it sooner). Leads never auto-cover.
110
            var autoCovered = !!r.nextScheduledDate;
111
            var statusCell = autoCovered
112
                    ? '<span class="label label-success" title="Also scheduled on ' + r.nextScheduledDate + '">Auto-covered</span>'
113
                    : '<span class="label label-warning">Deferred</span>';
114
            var typeCell = (r.type === 'Lead')
115
                    ? '<span class="label label-warning">Lead</span>'
116
                    : '<span class="label label-info">Visit</span>';
117
            var next = autoCovered
118
                    ? '<span style="color:#2e7d32; font-weight:600;">' + r.nextScheduledDate + '</span>'
119
                    : '<span style="color:#999;">—</span>';
120
            var safeName = (r.name || '').replace(/"/g, '&quot;');
121
            var action = '<button class="btn btn-xs btn-success def-reschedule"'
122
                    + ' data-id="' + r.id + '"'
123
                    + ' data-userid="' + r.authUserId + '"'
124
                    + ' data-username="' + (r.userName || '').replace(/"/g, '&quot;') + '"'
125
                    + ' data-type="' + (r.type === 'Lead' ? 'lead' : 'visit') + '"'
126
                    + ' data-deferdate="' + (r.deferredDate || '') + '"'
127
                    + ' data-name="' + safeName + '">Reschedule</button> '
128
                    + '<button class="btn btn-xs btn-default def-cancel" data-id="' + r.id + '">Cancel</button>';
129
            html += '<tr>'
130
                    + '<td>' + (r.userName || '') + '</td>'
131
                    + '<td><span class="label label-primary">' + (r.deferredDate || '') + '</span></td>'
132
                    + '<td>' + typeCell + '</td>'
133
                    + '<td>' + (r.name || '') + '</td>'
134
                    + '<td>' + (r.reason || '') + '</td>'
135
                    + '<td>' + statusCell + '</td>'
136
                    + '<td>' + next + '</td>'
137
                    + '<td>' + action + '</td>'
138
                    + '</tr>';
139
        });
140
        $('#defRows').html(html);
141
    }
142
 
143
    // Cancel
144
    $(document).on('click', '.def-cancel', function () {
145
        var id = $(this).data('id');
146
        if (!confirm('Cancel this deferred visit? It will be dropped (no re-visit).')) return;
147
        $.ajax({
148
            url: context + '/beatPlan/deferred/action',
149
            type: 'POST', contentType: 'application/json',
150
            data: JSON.stringify({deferredId: id, action: 'cancel'}),
151
            success: function () {
152
                loadDeferred();
153
            },
154
            error: function (xhr) {
155
                alert(serverMsg(xhr, 'Cancel failed'));
156
            }
157
        });
158
    });
159
 
160
    // Reschedule → open the beat-plan calendar window scoped to that sales person,
161
    // in "deferred-assign" mode. The head clicks an upcoming beat there to drop the
162
    // deferred lead/partner into it. On close, reload (the assigned item drops off).
163
    $(document).on('click', '.def-reschedule', function () {
164
        var id = $(this).data('id');
165
        var userId = $(this).data('userid');
166
        var userName = $(this).data('username') || '';
167
        var type = $(this).data('type') || 'visit';
168
        var name = $(this).data('name') || '';
169
        var deferDate = $(this).data('deferdate') || '';
170
        var url = context + '/beatPlanWindow'
171
                + '?autoUserId=' + userId
172
                + '&autoUserName=' + encodeURIComponent(userName)
173
                + '&assignDeferredId=' + id
174
                + '&deferType=' + encodeURIComponent(type)
175
                + '&deferDate=' + encodeURIComponent(deferDate)
176
                + '&deferName=' + encodeURIComponent(name);
177
        $('#defCalTitle').text('Reschedule "' + name + '" into a beat — ' + userName);
178
        $('#defCalFrame').attr('src', url);
179
        $('#defCalModal').modal('show');
180
    });
181
 
182
    // Reload the list when the calendar window closes (item may have been assigned)
183
    $('#defCalModal').on('hidden.bs.modal', function () {
184
        $('#defCalFrame').attr('src', '');
185
        loadDeferred();
186
    });
187
 
188
    function serverMsg(xhr, fallback) {
189
        try {
190
            var err = JSON.parse(xhr.responseText);
191
            if (err && err.response) {
192
                if (typeof err.response === 'string') return err.response;
193
                if (err.response.message) return err.response.message;
194
            }
195
        } catch (e) {
196
        }
197
        return fallback;
198
    }
199
</script>