| 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 |
});
|