Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
37823 amit 1
// Sellers & Warehouses screen. The server re-checks every rule (WarehouseSetupValidator); these checks only save a
2
// round trip. A refused request comes back as a 400 whose text the ajax helpers show as is.
3
var SellerSetup = (function () {
28300 tejbeer 4
 
37823 amit 5
    var GSTIN = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][0-9A-Z]Z[0-9A-Z]$/;
28300 tejbeer 6
 
37846 amit 7
    function loadPage(then) {
37823 amit 8
        doGetAjaxRequestHandler(context + "/getAllSeller", function (response) {
9
            $('#main-content').html(response);
37846 amit 10
            formatAmounts();
11
            if (typeof then === 'function') {
12
                then();
13
            }
37823 amit 14
        });
15
    }
28300 tejbeer 16
 
37823 amit 17
    function loadSeller(sellerId) {
18
        doGetAjaxRequestHandler(context + "/getSellerWareHouse?sellerId=" + sellerId, function (response) {
37846 amit 19
            var container = $('.seller-setup .warehouse-container');
20
            container.html(response);
21
            $('html, body').animate({scrollTop: container.offset().top - 60}, 200);
37823 amit 22
        });
23
    }
28300 tejbeer 24
 
37846 amit 25
    // Reload the page so the overview, counts and an open seller panel all show the change.
26
    function reload() {
27
        var sellerId = currentSellerId();
28
        loadPage(sellerId ? function () {
29
            loadSeller(sellerId);
30
        } : null);
31
    }
32
 
33
    function formatAmounts() {
34
        $('.seller-setup .inr').each(function () {
35
            var amount = parseInt($(this).text(), 10);
36
            if (!isNaN(amount)) {
37
                $(this).text(amount.toLocaleString('en-IN'));
38
            }
39
        });
40
    }
41
 
42
    var STATUS_EFFECT = {
43
        ACTIVE: 'It shows on dashboards and in warehouse screens, and partner stores can be assigned to it.',
44
        SUSPENDED: 'It leaves dashboards and takes no new orders, but stays in warehouse screens so its stock and'
45
            + ' returns can be cleared. Refused while franchise stores or brand mapping still point at it.',
46
        INACTIVE: 'It is closed for good: hidden everywhere except the name on old records. Refused while it'
47
            + ' holds stock, has unshipped orders, or franchise stores or brand mapping still point at it.'
48
    };
49
 
37823 amit 50
    function currentSellerId() {
51
        return $('.seller-warehouses').data('seller-id');
52
    }
28300 tejbeer 53
 
37823 amit 54
    // A page or panel reload replaces the modal's markup, so wait until it has closed and its backdrop is gone.
55
    function closeThen(modalSelector, next) {
56
        $(modalSelector).one('hidden.bs.modal', next).modal('hide');
57
    }
28300 tejbeer 58
 
37823 amit 59
    function value(selector) {
60
        return $.trim($(selector).val() || '');
61
    }
28300 tejbeer 62
 
37823 amit 63
    function postJson(url, payload, onSuccess) {
64
        doPostAjaxRequestWithJsonHandler(url, JSON.stringify(payload), onSuccess);
65
    }
28300 tejbeer 66
 
37823 amit 67
    // Same split as WarehouseAddressMaster.getCustomAddress(): the last comma segment is the city, the rest is
68
    // divided between two lines.
69
    function invoiceLines(address, city) {
70
        var parts = address.split(',').map(function (part) {
71
            return $.trim(part);
72
        }).filter(function (part) {
73
            return part.length > 0;
74
        });
75
        var midpoint = Math.floor(parts.length / 2);
76
        return {
77
            line1: parts.slice(0, midpoint).join(', '),
78
            line2: parts.slice(midpoint).join(', '),
79
            city: city
80
        };
81
    }
28300 tejbeer 82
 
37823 amit 83
    function renderAddressPreview() {
84
        var address = value('#new-address-address');
85
        var city = value('#new-address-city');
86
        if (!address || !city) {
87
            $('#new-address-preview').text('-');
88
            return;
89
        }
90
        var lines = invoiceLines(address, city);
91
        var state = $('#new-address-state option:selected').val() ? $('#new-address-state option:selected').text() : '';
92
        var preview = $('<div>');
93
        [lines.line1, lines.line2, lines.city + ' - ' + value('#new-address-pin'), state].forEach(function (line) {
94
            if (line) {
95
                preview.append($('<div>').text(line));
96
            }
97
        });
98
        $('#new-address-preview').empty().append(preview.children());
99
    }
28300 tejbeer 100
 
37823 amit 101
    function createAddress() {
102
        var payload = {
103
            address: value('#new-address-address'),
104
            city: value('#new-address-city'),
105
            pin: value('#new-address-pin'),
106
            stateId: parseInt($('#new-address-state').val(), 10),
107
            contactPerson: value('#new-address-contact-person'),
108
            contactNumber: value('#new-address-contact-number')
109
        };
110
        if (!payload.address || !payload.city) {
111
            alert('Address and city are required');
112
            return;
113
        }
114
        if (payload.city.indexOf(',') >= 0) {
115
            alert('City must not contain a comma');
116
            return;
117
        }
118
        if (!/^\d{6}$/.test(payload.pin)) {
119
            alert('Pin must be 6 digits');
120
            return;
121
        }
122
        if (!payload.stateId && payload.stateId !== 0) {
123
            alert('Select a state');
124
            return;
125
        }
126
        if (!payload.contactPerson) {
127
            alert('Contact person is required');
128
            return;
129
        }
130
        if (!/^\d{10,15}$/.test(payload.contactNumber)) {
131
            alert('Contact number must be 10 to 15 digits');
132
            return;
133
        }
134
        postJson(context + '/createNewAddress', payload, function (response) {
135
            closeThen('#new-address-modal', loadPage);
136
        });
137
    }
28300 tejbeer 138
 
37823 amit 139
    function renderGstinHint() {
140
        var gstin = value('#new-seller-gstin').toUpperCase();
141
        if (!gstin) {
142
            $('#new-seller-gstin-hint').text('State and PAN are read from the GSTIN.');
143
        } else if (GSTIN.test(gstin)) {
144
            $('#new-seller-gstin-hint').text('State code ' + gstin.substring(0, 2) + ' ยท PAN ' + gstin.substring(2, 12));
145
        } else {
146
            $('#new-seller-gstin-hint').text('Not a valid GSTIN yet');
147
        }
148
    }
28300 tejbeer 149
 
37823 amit 150
    function createSeller() {
151
        var payload = {
152
            label: value('#new-seller-label'),
153
            gstin: value('#new-seller-gstin').toUpperCase(),
154
            address: value('#new-seller-address')
155
        };
156
        if (!payload.label || !payload.address) {
157
            alert('Label and registered address are required');
158
            return;
159
        }
160
        if (!GSTIN.test(payload.gstin)) {
161
            alert('GSTIN is not in the format the GST portal issues');
162
            return;
163
        }
164
        postJson(context + '/createNewSeller', payload, function () {
165
            closeThen('#new-seller-modal', loadPage);
166
        });
167
    }
28300 tejbeer 168
 
37823 amit 169
    function createWarehouse() {
170
        var sellerId = currentSellerId();
171
        var payload = {
172
            sellerId: sellerId,
173
            name: value('#new-warehouse-name'),
174
            prefix: value('#new-warehouse-prefix').toUpperCase(),
175
            addressId: parseInt($('#new-warehouse-address').val(), 10)
176
        };
177
        if (!payload.name) {
178
            alert('Warehouse name is required');
179
            return;
180
        }
181
        if (!/^[A-Z]{2,7}$/.test(payload.prefix)) {
182
            alert('Branch code must be 2 to 7 letters, no digits or symbols');
183
            return;
184
        }
185
        if (!payload.addressId) {
186
            alert('Select an address');
187
            return;
188
        }
189
        if (!confirm('Create warehouse ' + payload.name + ' with branch code ' + payload.prefix + '?')) {
190
            return;
191
        }
192
        postJson(context + '/createNewWarehouse', payload, function () {
193
            closeThen('#new-warehouse-modal', function () {
194
                loadSeller(sellerId);
195
            });
196
        });
197
    }
28300 tejbeer 198
 
37846 amit 199
    function setStatus(select) {
200
        var warehouseId = select.data('warehouse-id');
201
        var current = String(select.data('current'));
202
        var status = select.val();
203
        if (status === current) {
204
            return;
205
        }
206
        if (!confirm('Mark warehouse ' + warehouseId + ' ' + status + '?\n\n' + STATUS_EFFECT[status])) {
207
            select.val(current);
208
            return;
209
        }
210
        // A refusal comes back as a 400 the ajax helper shows; put the dropdown back until the page reloads.
211
        select.val(current);
212
        doPostAjaxRequestHandler(context + '/physicalWarehouse/' + warehouseId + '/status?status=' + status, reload);
213
    }
214
 
215
    function rename(button) {
37823 amit 216
        var warehouseId = button.data('warehouse-id');
37846 amit 217
        var label = prompt('Label for warehouse ' + warehouseId + ' (shown on dashboards, dropdowns and reports)',
218
            button.data('display-name') || '');
219
        if (label === null || $.trim(label) === '' || $.trim(label) === String(button.data('display-name'))) {
37823 amit 220
            return;
221
        }
37846 amit 222
        doPostAjaxRequestHandler(context + '/physicalWarehouse/' + warehouseId + '/displayName?displayName='
223
            + encodeURIComponent($.trim(label)), reload);
37823 amit 224
    }
28300 tejbeer 225
 
37846 amit 226
    function filterStatus(button) {
227
        var status = button.data('status');
228
        button.addClass('active').siblings().removeClass('active');
229
        $('.warehouse-overview tbody tr').each(function () {
230
            $(this).toggle(!status || $(this).data('status') === status);
231
        });
232
    }
233
 
234
    function sendStockAlert() {
235
        if (!confirm('Mail logistics, finance and leadership the stock lying in suspended or inactive warehouses'
236
            + ' now?')) {
237
            return;
238
        }
239
        doPostAjaxRequestHandler(context + '/warehouseStockAlert/send', function (response) {
240
            var result = typeof response === 'string' ? JSON.parse(response) : response;
241
            alert(result.summary || 'Done');
242
        });
243
    }
244
 
37823 amit 245
    function remapAddress() {
246
        var sellerId = currentSellerId();
247
        var warehouseId = $('#remap-address-modal').data('warehouse-id');
248
        var addressId = parseInt($('#remap-address').val(), 10);
249
        if (!addressId) {
250
            alert('Select an address');
251
            return;
252
        }
253
        if (!confirm('Change the address of warehouse ' + warehouseId + ' to #' + addressId
254
            + '? Its internal stores move to it as well.')) {
255
            return;
256
        }
257
        doPostAjaxRequestHandler(context + '/physicalWarehouse/' + warehouseId + '/address?addressId=' + addressId,
258
            function () {
259
                closeThen('#remap-address-modal', function () {
260
                    loadSeller(sellerId);
261
                });
262
            });
263
    }
28300 tejbeer 264
 
37823 amit 265
    function toggleAddress(button) {
266
        var addressId = button.data('address-id');
267
        var activate = String(button.data('active')) !== 'true';
268
        if (!activate && !confirm('Deactivate address #' + addressId + '? It will no longer be offered for new'
269
            + ' warehouses. Warehouses already on it keep printing it.')) {
270
            return;
271
        }
272
        doPostAjaxRequestHandler(context + '/warehouseAddress/' + addressId + '/active?active=' + activate, loadPage);
273
    }
28300 tejbeer 274
 
37823 amit 275
    return {
276
        loadPage: loadPage,
277
        loadSeller: loadSeller,
278
        renderAddressPreview: renderAddressPreview,
279
        renderGstinHint: renderGstinHint,
280
        createAddress: createAddress,
281
        createSeller: createSeller,
282
        createWarehouse: createWarehouse,
37846 amit 283
        setStatus: setStatus,
284
        rename: rename,
285
        filterStatus: filterStatus,
286
        sendStockAlert: sendStockAlert,
37823 amit 287
        remapAddress: remapAddress,
288
        toggleAddress: toggleAddress
289
    };
290
})();
28300 tejbeer 291
 
37823 amit 292
$(document).on('click', '.seller-index', function () {
293
    SellerSetup.loadPage();
28300 tejbeer 294
});
37823 amit 295
$(document).on('click', '.seller-setup .seller-open', function () {
296
    SellerSetup.loadSeller($(this).data('seller-id'));
28300 tejbeer 297
});
37823 amit 298
$(document).on('input change', '.seller-setup .address-preview-source', function () {
299
    SellerSetup.renderAddressPreview();
28300 tejbeer 300
});
37823 amit 301
$(document).on('input', '#new-seller-gstin', function () {
302
    SellerSetup.renderGstinHint();
303
});
304
$(document).on('click', '#new-address-submit', function () {
305
    SellerSetup.createAddress();
306
});
307
$(document).on('click', '#new-seller-submit', function () {
308
    SellerSetup.createSeller();
309
});
310
$(document).on('click', '#new-warehouse-submit', function () {
311
    SellerSetup.createWarehouse();
312
});
37846 amit 313
$(document).on('change', '.seller-setup .warehouse-status', function () {
314
    SellerSetup.setStatus($(this));
37823 amit 315
});
37846 amit 316
$(document).on('click', '.seller-setup .warehouse-rename', function () {
317
    SellerSetup.rename($(this));
318
});
319
$(document).on('click', '.seller-setup .warehouse-status-filter .btn', function () {
320
    SellerSetup.filterStatus($(this));
321
});
322
$(document).on('click', '.seller-setup .warehouse-stock-alert', function () {
323
    SellerSetup.sendStockAlert();
324
});
37823 amit 325
$(document).on('click', '.seller-setup .address-active-toggle', function () {
326
    SellerSetup.toggleAddress($(this));
327
});
328
$(document).on('click', '.seller-setup .warehouse-remap-open', function () {
329
    var button = $(this);
330
    $('#remap-warehouse-id').text(button.data('warehouse-id'));
331
    $('#remap-address').val(String(button.data('address-id') || ''));
332
    $('#remap-address-modal').data('warehouse-id', button.data('warehouse-id')).modal('show');
333
});
334
$(document).on('click', '#remap-address-submit', function () {
335
    SellerSetup.remapAddress();
336
});