Subversion Repositories SmartDukaan

Rev

Rev 37881 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
27187 amit.gupta 1
var customerId;
31083 amit.gupta 2
 
24440 amit.gupta 3
function formLoaded() {
32327 amit.gupta 4
    $("form#cd input").each(function () {
5
        $(this).attr('autocomplete', 'off');
6
    });
7
    $('form#cd').validate({
8
        rules: {
9
            name: {
10
                required: true
11
            },
12
            email: {
13
                required: true,
14
                email: true
15
            },
16
            line1: {
17
                required: true
18
            },
19
            state: {
20
                required: true
21
            },
22
            city: {
23
                required: true
24
            },
25
            pincode: {
26
                required: true,
27
                digits: true,
28
                minlength: 6,
29
                maxlength: 6,
30
            },
31
            phone: {
32
                required: true,
33
                minlength: 10,
34
                maxlength: 10,
35
                digits: true
36
            },
37
        },
38
        messages: {
39
            name: {
40
                required: "Required"
41
            },
42
            line1: {
43
                required: "Required"
44
            },
45
            state: {
46
                required: "State required"
47
            },
48
            city: {
49
                required: "City required"
50
            },
51
            email: {
52
                require: "Required"
53
            },
54
            pincode: {
55
                required: "Required",
56
                digits: "Invalid pin"
57
            },
58
            phone: {
59
                required: "Required",
60
                digits: "Invalid number",
61
                minlength: "Number should be of 10 digits"
62
            }
63
        },
64
        submitHandler: function (form, event) {
65
            event.preventDefault();
66
            var payload = orderDetailsPayload();
67
            if (!validateOrderDetails()) {
68
                alert("Please fix highlighted errors");
69
                return false;
70
            }
37881 ranu 71
            checkImeiEligibilityThenProceed(function () {
72
                doPostAjaxRequestWithJsonHandler(context + "/create-order", payload, function (response) {
73
                    emptyBag();
74
                    $('#main-content').html(response);
75
                });
32327 amit.gupta 76
            });
77
            return false; // required to block normal submit since you used
78
            // ajax
79
        }
31083 amit.gupta 80
 
32327 amit.gupta 81
    });
28339 tejbeer 82
 
34179 tejus.loha 83
 
32327 amit.gupta 84
    $('form#newaddress').validate({
85
        rules: {
86
            firstName: {
87
                required: true
88
            },
89
            line1: {
90
                required: true
91
            },
92
            state: {
93
                required: true
94
            },
95
            city: {
96
                required: true
97
            },
98
            pinCode: {
99
                required: true,
100
                digits: true,
101
                minlength: 6,
102
                maxlength: 6,
103
            },
104
            alternatePhone: {
105
                required: true,
106
                minlength: 10,
107
                maxlength: 10,
108
                digits: true
109
            },
110
        },
111
        messages: {
112
            firstName: {
113
                required: "Required"
114
            },
115
            line1: {
116
                required: "Required"
117
            },
118
            state: {
119
                required: "State required"
120
            },
121
            city: {
122
                required: "City required"
123
            },
124
            pinCode: {
125
                required: "Required",
126
                digits: "Invalid pin"
127
            },
128
            alternatePhone: {
129
                required: "Required",
130
                digits: "Invalid number",
131
                minlength: "Number should be of 10 digits"
132
            }
133
        },
134
        submitHandler: function (form, event) {
135
            event.preventDefault();
36064 aman 136
            if ($(form).data('submitting')) return;
137
            $(form).data('submitting', true);
32327 amit.gupta 138
            let customerAddress = {};
139
            customerAddress['name'] = $("#firstName").val();
140
            customerAddress['lastName'] = $("#lastName").val();
141
            customerAddress['line1'] = $("#line1").val();
142
            customerAddress['line2'] = $("#line2").val();
143
            customerAddress['landmark'] = $("#landmark").val();
144
            customerAddress['city'] = $("#city").val();
145
            customerAddress['state'] = $('select[name=state] option:selected').val();
146
            customerAddress['pinCode'] = $("#pinCode").val();
147
            customerAddress['phoneNumber'] = $("#alternatePhone").val();
148
            customerAddress['country'] = "India";
149
            doPostAjaxRequestWithJsonHandler(`${context}/customer/address?customerId=${customerId}`, JSON.stringify(customerAddress), function (response) {
150
                $("#address-body").prepend(getAddressTr(response.response));
151
                $('#newaddressModal').modal('toggle');
152
                $("#address-body").find('a.select-address').click();
36064 aman 153
                $(form).data('submitting', false);
32327 amit.gupta 154
            });
155
        }
31083 amit.gupta 156
 
32327 amit.gupta 157
    });
31083 amit.gupta 158
 
32327 amit.gupta 159
    $("input.unitPrice").on('change', function () {
160
        var $element = $(this);
161
        var unitPrice = parseFloat($element.val());
162
        if (!isNaN(unitPrice)) {
163
            var itemType = parseFloat($(this).closest('tr').find('.serialNumber').attr("itemType"));
164
            var mopPrice = parseFloat($(this).attr('mopPrice'));
165
            var isMop = JSON.parse($(this).attr('isMop'));
166
            var dp = parseFloat($(this).attr('dp'));
167
            var mrp = parseFloat($(this).attr('mrp'));
35459 amit 168
            if (mrp != 0 && unitPrice > mrp) {
32327 amit.gupta 169
                alert("Selling Price should not be greater than MRP");
170
                $element.addClass("border-highlight");
171
            } else if (!accessoriesDeals && unitPrice < mopPrice) {
172
                alert("Selling Price must be greater than equal to MOP");
173
                $element.addClass("border-highlight");
35459 amit 174
            } else if (itemType == 'SERIALIZED' && unitPrice < mopPrice) {
32327 amit.gupta 175
                if (isMop) {
176
                    alert("Selling Price must be greater than equal to MOP");
177
                    $element.addClass("border-highlight");
178
                }
35459 amit 179
            } else if (itemType == 'NON_SERIALIZED' && unitPrice < dp) {
32327 amit.gupta 180
                alert("Selling Price must be greater than equal to DP");
181
                $element.addClass("border-highlight");
182
            } else {
183
                $element.removeClass("border-highlight");
184
            }
185
            // Clear insurance values if price changes
186
            $(this).closest('tr').find('.insuranceid').val("");
187
            $(this).closest('tr').find('.insuranceamount').val("0");
188
        }
32468 amit.gupta 189
        //calculateTotalAmount();
32327 amit.gupta 190
    });
191
    customerInfo = $("div.customerinfo").html();
192
    billingInfo = $("div.billinginfo").html();
28339 tejbeer 193
 
32327 amit.gupta 194
    $("input.search-phone").change(function () {
195
        resetInputs();
196
        var mobileNumber = $(this).val();
32468 amit.gupta 197
        console.log(mobileNumber);
32327 amit.gupta 198
        if (mobileNumber.length < 10 || mobileNumber.length > 10) {
199
            alert("Mobile Number is must be 10 digits");
200
            return false;
201
        } else {
202
            writeOldCustomerDetailsByMobileNumber(mobileNumber);
203
        }
204
    });
28339 tejbeer 205
 
32327 amit.gupta 206
    $(document).on('click', 'button.new-address-btn', function () {
207
        $('#newaddressModal').modal({show: true});
208
    });
28339 tejbeer 209
 
32327 amit.gupta 210
    $(document).on('click', 'button.mk_add_email', function () {
211
        let customerObj = {};
212
        customerObj['customerId'] = customerId;
213
        customerObj['emailId'] = $("#emailId").val();
214
        if (validateEmail(customerObj['emailId'])) {
215
            doPostAjaxRequestWithJsonHandler(`${context}/customer/add-email`, JSON.stringify(customerObj), function (response) {
216
                alert("Email added");
217
                $("input.search-phone").val(customerObj['mobileNumber']).change();
218
            });
219
        } else {
220
            alert("Invalid email id");
221
        }
28339 tejbeer 222
 
32327 amit.gupta 223
    });
224
    $(document).on('click', 'button.mk_add_customer', function () {
35459 amit 225
        customerObj = {}
226
        if ($("input.firstName").val().length == 0) {
32327 amit.gupta 227
            alert("First Name is required");
228
            return false;
229
        }
230
        customerObj['firstName'] = $("input.firstName").val();
231
        customerObj['lastName'] = $("input.lastName").val();
232
        customerObj['emailId'] = $("#emailId").val();
35459 amit 233
 
234
        console.log(customerObj['emailId']);
32327 amit.gupta 235
        customerObj['mobileNumber'] = $("input.phone").val();
31855 tejbeer 236
 
32327 amit.gupta 237
        if (customerObj['emailId']) {
238
            if (!validateEmail(customerObj['emailId'])) {
239
                alert("Invalid email id");
240
                return false;
241
            }
242
        }
31855 tejbeer 243
 
244
 
32327 amit.gupta 245
        doPostAjaxRequestWithJsonHandler(`${context}/customer/add`, JSON.stringify(customerObj), function (response) {
246
            alert("Customer added");
247
            $("input.search-phone").change();
248
        });
31855 tejbeer 249
 
28339 tejbeer 250
 
32327 amit.gupta 251
    });
252
    $(document).on('click', 'a.select-address', function () {
253
        $(this).closest('table').data("addressselected", "true").find('td').css("font-weight", "normal");
254
        $(this).closest('tr').find('td').css("font-weight", "bold");
255
        selectedAddressId = $(this).data("addressid");
256
    });
257
    $(document).on('click', 'button.btn-add-address', function () {
36064 aman 258
        var $btn = $(this);
259
        if ($btn.prop('disabled')) return;
260
        $btn.prop('disabled', true);
32327 amit.gupta 261
        $("form#newaddress").submit();
36064 aman 262
        setTimeout(function () {
263
            $btn.prop('disabled', false);
264
        }, 2000);
32327 amit.gupta 265
    });
28339 tejbeer 266
 
36064 aman 267
    $('#newaddressModal').on('hidden.bs.modal', function () {
268
        $('form#newaddress').data('submitting', false);
269
    });
270
 
32327 amit.gupta 271
}
28339 tejbeer 272
 
273
function validateOrderDetails() {
32327 amit.gupta 274
    var sNumbers = [];
275
    var error = false;
276
    $("form#cd input.serialNumber").each(function () {
35232 ranu 277
        var input = $(this).val().trim();
278
        var itemType = $(this).attr("itemType");
279
        $(this).removeClass("border-highlight");
280
 
281
        if (itemType !== 'SERIALIZED') {
282
            return;
283
        }
284
 
285
        // Split multiple serial numbers by comma
286
        var serials = input.split(',').map(s => s.trim()).filter(s => s !== "");
287
 
288
        // Check for empty or duplicate
289
        for (let sn of serials) {
290
            if (!sn || sNumbers.indexOf(sn) !== -1) {
32329 amit.gupta 291
                error = true;
292
                $(this).addClass("border-highlight");
293
            }
35232 ranu 294
            sNumbers.push(sn);
32327 amit.gupta 295
        }
35232 ranu 296
    });
28339 tejbeer 297
 
32327 amit.gupta 298
    $("form#cd input.unitPrice").each(function () {
299
        var input = $(this).val().trim();
300
        $(this).removeClass("border-highlight");
301
        if (!input || parseInt(input) <= 0 || isNaN(input)) {
302
            error = true;
303
            $(this).addClass("border-highlight");
304
        }
305
    });
28339 tejbeer 306
 
32327 amit.gupta 307
    var gstNumber = $("form#cd input[name=gstNumber]").val();
308
    $("form#cd input[name=gstNumber]").removeClass("border-highlight");
35459 amit 309
    if (gstNumber.length > 0 && gstNumber.length != 15) {
32327 amit.gupta 310
        alert("Please provide valid gstNumber");
311
        error = true;
312
        $("form#cd input[name=gstNumber]").addClass("border-highlight");
313
    }
28339 tejbeer 314
 
32327 amit.gupta 315
    var amount = 0;
316
    var netPayableAmount = parseFloat($("form#cd input.netPayableAmount").val());
317
    $("form#cd input.amount").each(function () {
35459 amit 318
        if ($(this).val() == "") {
32327 amit.gupta 319
            $(this).val(0);
320
        }
321
        var tmpAmount = parseFloat($(this).val());
322
        amount = amount + tmpAmount;
323
    });
28339 tejbeer 324
 
35459 amit 325
    console.log(amount);
326
    console.log(netPayableAmount);
327
 
328
    if (amount != netPayableAmount) {
32327 amit.gupta 329
        if (amount < netPayableAmount) {
330
            alert("[" + (netPayableAmount - amount) + "] is more required to complete the payment");
331
        } else {
332
            alert("[" + (amount - netPayableAmount) + "] is extra amount, please reduce the amount");
333
        }
334
        $("form#cd input.netPayableAmount").each(function () {
335
            $(this).addClass("border-highlight");
336
        });
337
        error = true;
338
    }
28339 tejbeer 339
 
32327 amit.gupta 340
    if (error) {
341
        return false;
342
    }
343
    return true;
28339 tejbeer 344
 
23347 ashik.ali 345
}
346
 
27187 amit.gupta 347
 
28339 tejbeer 348
function getSerialNumbersFromOrder($el) {
32327 amit.gupta 349
    var $serialNumberElement = $el.find('.serialNumber');
35459 amit 350
    if ($serialNumberElement.val() == '') {
32327 amit.gupta 351
        return null;
352
    }
353
    var insuranceAmount = parseFloat($el.find('.insuranceamount').val());
35459 amit 354
    if (insuranceAmount > 0) {
355
        insurance = true;
356
        globalInsurace = true;
357
    } else {
358
        insurance = false;
359
    }
360
    return {'serialNumber': $serialNumberElement.val(), 'insurance': insurance, 'amount': insuranceAmount}
23347 ashik.ali 361
}
362
 
28339 tejbeer 363
function orderDetailsPayload() {
32327 amit.gupta 364
    var priceQtyArray = [];
365
    var customerObj = {};
366
    var paymentOptionIdAmount = [];
367
    var globalInsurance = false;
28339 tejbeer 368
 
32327 amit.gupta 369
    $("#order-items").find("tr:not(:first-child)").each(function (index, el) {
35459 amit 370
        console.log("el------------", el);
371
            // console.log(index);
34179 tejus.loha 372
            var $el = $(el);
373
            var $customerOfferItemId = $el.find('.offerSelect');
374
            var $unitPriceElement = $el.find('.unitPrice');
375
            var itemId = parseInt($unitPriceElement.attr("itemId"));
376
            var qty = parseInt($unitPriceElement.attr("quantity"));
377
            var found = false;
32816 ranu 378
            var customSerialNumberEl = $(el).find('.customSerialNumber');
34179 tejus.loha 379
            let tmpObj;
380
            let filteredList = priceQtyArray.filter(x => x.itemId === itemId);
381
            if (filteredList.length === 0) {
382
                var $discountElement = $el.find('.discount');
383
                var $poiId = $el.find('.poiId');
384
                var unitPrice = parseFloat($unitPriceElement.val());
385
                var discount = parseFloat($discountElement.val());
386
                var poiId = $poiId.val();
34805 ranu 387
                var customerOfferItemId = [];
388
                if ($customerOfferItemId && $customerOfferItemId.length > 0) {
389
                    var selectedOption = $customerOfferItemId.find("option:selected");
390
                    var offerIds = selectedOption.data("customeroffer-ids");
391
                    if (offerIds) {
392
                        customerOfferItemId = offerIds.toString().split(",").map(id => id.trim());
393
                    }
34179 tejus.loha 394
                }
33795 ranu 395
 
34179 tejus.loha 396
                if (isNaN(discount)) {
397
                    discount = 0;
398
                }
399
                let customSerialNumbers = [];
32816 ranu 400
 
34179 tejus.loha 401
                if (customSerialNumberEl.val() !== '') {
402
                    customSerialNumbers = customSerialNumberEl.val().split(",").map(function (serial) {
403
                        return serial.trim(); // Trim spaces from each serial number
404
                    });
32816 ranu 405
 
34179 tejus.loha 406
                    if (customSerialNumbers.length !== qty) {
407
                        alert("Please add all serial numbers");
408
                        return false;
409
                    }
32816 ranu 410
                }
411
 
34179 tejus.loha 412
                tmpObj = {
413
                    itemId: itemId,
414
                    poiId: poiId,
415
                    sellingPrice: unitPrice - discount,
416
                    quantity: 0,
417
                    customerOfferItemId: customerOfferItemId,
418
                    discountAmount: discount,
419
                    customSerialNumbers: customSerialNumberEl.val().split(","),
420
                    serialNumberDetails: []
421
                };
32816 ranu 422
 
34179 tejus.loha 423
                priceQtyArray.push(tmpObj);
424
            } else {
425
                tmpObj = filteredList[0];
426
            }
28339 tejbeer 427
 
32816 ranu 428
            tmpObj.quantity += qty;
32328 amit.gupta 429
 
35232 ranu 430
            // Handle serial numbers and insurance per row
431
            var $serialNumberElement = $el.find('.serialNumber');
432
            var serialNumbers = $serialNumberElement.val()
433
                ? $serialNumberElement.val().split(',').map(s => s.trim())
434
                : [];
435
            tmpObj.customSerialNumbers = serialNumbers;
34798 ranu 436
 
35232 ranu 437
// Get insurance details
438
            var insuranceEle = $el.find('.insuranceamount');
439
            var insuranceIds = ($el.find('.insuranceid').val() || "").split(',');
440
            var correlationIds = ($el.find('.correlationid').val() || "").split(',');
441
            var amounts = (insuranceEle.data('all-amounts') || "").toString().split(',');
34798 ranu 442
 
35232 ranu 443
            var ram = $el.find('.ram').val();
444
            var memory = $el.find('.memory').val();
445
            var rawDate = $el.find('.mfgdate').val();
446
            var mfgDate = rawDate ? new Date(rawDate).toISOString().split('.')[0] : "";
32816 ranu 447
 
35232 ranu 448
// Map each serial number to its corresponding insurance
449
            for (let i = 0; i < serialNumbers.length; i++) {
450
                let sn = serialNumbers[i];
451
                if (insuranceIds[i]) {
452
                    for (let j = 0; j < insuranceIds.length; j++) {
453
                        let serialNumberDetail = {
454
                            serialNumber: sn,
455
                            insurance: insuranceIds[j] || "",
456
                            correlationId: correlationIds[i] || "",
457
                            amount: parseFloat(amounts[j] || 0),
458
                            ram: ram,
459
                            memory: memory,
460
                            mfgDate: mfgDate
461
                        };
462
                        tmpObj.serialNumberDetails.push(serialNumberDetail);
463
                    }
464
                } else {
465
                    let serialNumberDetail = {
466
                        serialNumber: sn,
467
                        insurance: insuranceIds[i] || "",
468
                        correlationId: correlationIds[i] || "",
469
                        amount: parseFloat(amounts[i] || 0),
470
                        ram: ram,
471
                        memory: memory,
472
                        mfgDate: mfgDate
473
                    };
474
                    tmpObj.serialNumberDetails.push(serialNumberDetail);
475
                }
476
            }
32327 amit.gupta 477
        }
32816 ranu 478
    )
479
    ;
23873 amit.gupta 480
 
28339 tejbeer 481
 
32327 amit.gupta 482
    customerObj['gstNumber'] = $("form#cd input[name=gstNumber]").val();
35459 amit 483
    if (customerId == undefined) {
32327 amit.gupta 484
        alert("Please choose customer");
485
        return false;
486
    }
35459 amit 487
    if ($("#customer-address").data("addressselected") == "true") {
32327 amit.gupta 488
        alert("Please select address");
489
        return false;
490
    }
491
    customerObj['customerId'] = customerId;
32816 ranu 492
// Check if selectedAddressId is defined and not empty
32627 ranu 493
    if (typeof selectedAddressId !== "undefined" && selectedAddressId !== null && selectedAddressId !== "") {
494
        customerObj['customerAddressId'] = selectedAddressId;
495
    } else {
496
        customerObj['customerAddressId'] = null;
497
    }
498
 
32327 amit.gupta 499
    customerObj['gender'] = $("#gender").val();
35549 ranu 500
    customerObj['dateOfBirth'] = $("#dateOfBirth").val();
28339 tejbeer 501
 
502
 
32327 amit.gupta 503
    var paymentOptionSize = parseInt($('#payment-option-id-amount-container').attr("paymentOptionSize"));
35459 amit 504
// console.log("paymentOptionSize = "+paymentOptionSize);
32327 amit.gupta 505
    for (var index = 0; index < paymentOptionSize; index++) {
506
        var paymentOptionAmount = 0.0;
35459 amit 507
        if ($('#paymentOptionIdAmount' + index).val() != "") {
32327 amit.gupta 508
            paymentOptionAmount = parseFloat($('#paymentOptionIdAmount' + index).val());
509
        }
510
        var paymentOptionId = $('#paymentOptionIdAmount' + index).attr("paymentOptionId");
511
        var paymentOptionIdAmountObject = {};
512
        paymentOptionIdAmountObject['paymentOptionId'] = paymentOptionId;
513
        paymentOptionIdAmountObject['amount'] = paymentOptionAmount;
514
        paymentOptionIdAmount.push(paymentOptionIdAmountObject);
515
    }
516
    var retObj = {};
517
    retObj['fofoOrderItems'] = (priceQtyArray);
518
    retObj['customer'] = (customerObj);
519
    retObj['paymentOptions'] = (paymentOptionIdAmount);
520
    retObj['poId'] = $('#poid').val();
28339 tejbeer 521
 
32327 amit.gupta 522
    retObj['poItemId'] = $('#poItemId').val();
36064 aman 523
    retObj['sendInvoiceOnWhatsApp'] = $('#sendInvoiceOnWhatsApp').is(':checked');
28339 tejbeer 524
 
35459 amit 525
    console.log(retObj);
32327 amit.gupta 526
    return JSON.stringify(retObj);
23347 ashik.ali 527
}
528
 
27187 amit.gupta 529
function resetInputs() {
32327 amit.gupta 530
    $("div.customerinfo").html(customerInfo);
531
    $("div.billinginfo").html(billingInfo).hide();
27187 amit.gupta 532
}
31083 amit.gupta 533
 
28339 tejbeer 534
function writeOldCustomerDetailsByMobileNumber(mobileNumber) {
32327 amit.gupta 535
    doAjaxRequestHandler(context + "/customer/mobileNumber?mobileNumber=" + mobileNumber, "GET", function (response) {
35459 amit 536
        if (response.response == '') {
32327 amit.gupta 537
            return;
538
        }
539
        var customer = response.response;
35459 amit 540
        if (customer == null) {
32327 amit.gupta 541
            $('input.phone').attr('value', mobileNumber).attr('readonly', true);
542
            $('button.mk_add_customer').show();
35459 amit 543
 
32327 amit.gupta 544
            return;
545
        }
546
        $('input.firstName').attr('value', customer.firstName).attr('readonly', true);
547
        $('input.lastName').attr('value', customer.lastName).attr('readonly', true);
548
        $('input.phone').attr('value', customer.mobileNumber).attr('readonly', true);
35459 amit 549
        if (customer.emailId != null && customer.emailId != '') {
32327 amit.gupta 550
            $('#emailId').attr('value', customer.emailId).attr('readonly', true);
35459 amit 551
            console.log('helo');
32327 amit.gupta 552
        } else {
553
            $('button.mk_add_email').show();
554
        }
555
        $('#firstName').val(customer.firstName);
556
        $('#lastName').val(customer.lastName);
557
        $('#alternatePhone').val(customer.mobileNumber);
558
        customerId = customer.customerId;
559
        $("div.billinginfo").show();
35459 amit 560
        trs = [];
561
        if (customer.addresses != null) {
562
            for (address of customer.addresses) {
563
                if (pendingPO != null) {
564
 
565
                    if (pendingPO.customerAddressId == address.id) {
32327 amit.gupta 566
                        trs.push(getAddressTr(address));
567
                    }
568
                } else {
569
                    trs.push(getAddressTr(address));
570
                }
571
            }
572
        }
573
        $("#address-body").html(trs.join(""));
35459 amit 574
 
32327 amit.gupta 575
    });
27187 amit.gupta 576
}
31083 amit.gupta 577
 
27187 amit.gupta 578
function getAddressTr(address) {
32327 amit.gupta 579
    var tr = [];
580
    tr.push(`<tr><td>${address.name} ${address.lastName}</td>`);
581
    tr.push(`<td>${address.line1}, ${address.line2}</td>`);
582
    tr.push(`<td>${address.city}</td>`);
583
    tr.push(`<td>${address.state}</td>`);
584
    tr.push(`<td>${address.pinCode}</td>`);
585
    tr.push(`<td>${address.phoneNumber}</td>`);
586
    tr.push(`<td><a class="select-address" href="javascript:void(0);" data-addressid="${address.id}">Select address</a></td></tr>`);
587
    return tr.join("");
27693 amit.gupta 588
}
31083 amit.gupta 589
 
27693 amit.gupta 590
function validateEmail(email) {
32327 amit.gupta 591
    const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
592
    return re.test(String(email).toLowerCase());
31083 amit.gupta 593
}
34179 tejus.loha 594
function sendInvoiceOnWApp(orderId){
595
    let whatsAppMobile = $('#whatsApp-invoice-number').val();
34204 tejus.loha 596
    if(!whatsAppMobile){
597
        alert('Please enter valid whatsApp number');
598
        return;
599
    }
600
    if(whatsAppMobile.length<10){
601
        alert('Mobile number must be at least 10 digits');
602
        return;
603
    }
604
    if(confirm('Are you sure you want to send invoice on whatsApp?')){
605
        doPutAjaxRequestHandler(`${context}/sendInvoiceOnWhatsApp?orderId=${orderId}&whatsAppMobile=${whatsAppMobile}`, function (response) {
606
            console.log("sendInvoiceOnWhatsApp res - ",response);
607
            if(response){
608
                alert('Invoice send successfully on whatsApp');
609
            }
610
        });
611
    }else {
612
        return;
613
    }
34179 tejus.loha 614
 
34204 tejus.loha 615
 
34179 tejus.loha 616
}
37881 ranu 617
 
618
// =============================================================================
619
// IMEI activation-age check for Navratri scratch coupon eligibility.
620
//
621
// Two touch-points:
622
// 1. On blur/change of an IMEI input → inline ✓/⚠ note under the field so the
623
//    partner knows upfront whether that IMEI will earn a coupon.
624
// 2. On Create Order submit → checkImeiEligibilityThenProceed() runs a batch
625
//    check and, if any IMEI is stale, shows a confirm() dialog. The partner can
626
//    cancel (bill not created) or OK (bill created without a scratch coupon
627
//    for the stale IMEIs). Fresh IMEIs still earn coupons as normal.
628
//
629
// Never silently blocks the bill — the eligibility endpoint being down means
630
// we skip the check (fail-open) rather than freeze billing.
631
// =============================================================================
632
 
633
/**
634
 * Collect every IMEI entered on the form, hit /scratch-eligibility for each,
635
 * and only invoke onProceed() once we're sure the partner wants to continue.
636
 * - All eligible → onProceed() fires immediately after the checks finish.
637
 * - Any ineligible → confirm() dialog listing the stale IMEIs; onProceed only
638
 *   fires if the partner clicks OK.
639
 * - Endpoint error / no IMEIs → onProceed() fires without the dialog.
640
 */
641
function checkImeiEligibilityThenProceed(onProceed) {
642
    var imeis = [];
643
    $("form#cd input.serialNumber").each(function () {
644
        var raw = ($(this).val() || '').trim();
645
        if (!raw) return;
646
        raw.split(',').forEach(function (s) {
647
            var sn = s.trim();
648
            if (sn) imeis.push(sn);
649
        });
650
    });
651
    if (imeis.length === 0) {
652
        onProceed();
653
        return;
654
    }
655
 
656
    var stale = [];
657
    var pending = imeis.length;
658
    imeis.forEach(function (imei) {
659
        $.ajax({
660
            url: (typeof context !== 'undefined' ? context : '') + '/scratch-eligibility?imei=' + encodeURIComponent(imei),
661
            method: 'GET',
662
            dataType: 'json',
663
            success: function (data) {
37886 ranu 664
                // applicable:false → no scratch offer running → no stale entry → no popup
665
                if (data && data.applicable !== false && data.eligible === false) {
37881 ranu 666
                    stale.push({imei: imei, message: data.message});
667
                }
668
            },
669
            error: function () {
670
                // Endpoint down or network blip — don't hold up the bill.
671
            },
672
            complete: function () {
673
                pending--;
674
                if (pending === 0) finalize();
675
            }
676
        });
677
    });
678
 
679
    function finalize() {
680
        if (stale.length === 0) {
681
            onProceed();
682
            return;
683
        }
684
        var msg = "⚠ The following IMEI(s) are NOT eligible for the Navratri scratch coupon:\n\n";
685
        stale.forEach(function (r) {
686
            msg += "• " + r.imei + "\n  " + (r.message || 'Activated more than 2 days ago') + "\n\n";
687
        });
688
        msg += "The bill will be created, but NO scratch coupon will be awarded for these IMEIs.\n\nDo you want to continue?";
689
        if (confirm(msg)) {
690
            onProceed();
691
        }
692
    }
693
}
694
 
695
 
696
// Also fire the IMEI check whenever the Unit Price is entered/edited, since
697
// the IMEI input itself is often readonly (populated when the item is added)
698
// and never emits a blur event of its own. Price entry is a real user action
699
// that happens on every bill, so it's a reliable moment to re-check the row.
700
$(document).on('blur change', 'input.unitPrice', function () {
701
    var $row = $(this).closest('tr');
702
    $row.find('input.serialNumber').each(function () {
703
        $(this).trigger('blur');
704
    });
705
});
706
 
707
$(document).on('blur change', 'input.serialNumber', function () {
708
    var $input = $(this);
709
    var raw = ($input.val() || '').trim();
710
    var $cell = $input.closest('td');
711
    var $note = $cell.find('.scratch-eligibility-note');
712
    if ($note.length === 0) {
713
        $note = $('<div class="scratch-eligibility-note" style="margin-top:4px;line-height:1.3;"></div>');
714
        // Place below the entire input-group (so it spans the cell, not just the input width).
715
        $input.closest('.input-group').after($note);
716
    }
717
    $note.empty();
718
    if (raw === '') {
719
        return;
720
    }
721
    var imeis = raw.split(',')
722
        .map(function (s) {
723
            return s.trim();
724
        })
725
        .filter(function (s) {
726
            return s !== '';
727
        });
728
    imeis.forEach(function (imei) {
729
        $.ajax({
730
            url: (typeof context !== 'undefined' ? context : '') + '/scratch-eligibility?imei=' + encodeURIComponent(imei),
731
            method: 'GET',
732
            dataType: 'json',
733
            success: function (data) {
734
                if (!data) return;
37886 ranu 735
                // Skip rendering when no scratch offer is live — the backend sets
736
                // applicable:false in that case and the whole badge is irrelevant.
737
                if (data.applicable === false) return;
37881 ranu 738
                var eligible = data.eligible === true;
739
                // Shortened message — the IMEI is already visible in the input right above.
740
                var short;
741
                if (data.daysSinceActivation == null) {
742
                    short = 'Fresh IMEI — coupon will be awarded';
743
                } else if (eligible) {
744
                    short = 'Activated ' + data.daysSinceActivation + 'd ago — coupon will be awarded';
745
                } else {
746
                    short = 'Activated ' + data.daysSinceActivation + 'd ago — NOT eligible for coupon';
747
                }
748
                var bg = eligible ? '#e9f6ec' : '#fdecee';
749
                var color = eligible ? '#1e6b2a' : '#a7101f';
750
                var border = eligible ? '#b7e0bf' : '#f1b4bb';
751
                var icon = eligible ? '✓' : '⚠';
752
                $('<div></div>')
753
                    .css({
754
                        display: 'inline-block',
755
                        maxWidth: '100%',
756
                        padding: '3px 8px',
757
                        marginTop: imeis.length > 1 ? '3px' : '0',
758
                        background: bg,
759
                        color: color,
760
                        border: '1px solid ' + border,
761
                        borderRadius: '4px',
762
                        fontSize: '11px',
763
                        fontWeight: 600,
764
                        whiteSpace: 'nowrap',
765
                        overflow: 'hidden',
766
                        textOverflow: 'ellipsis'
767
                    })
768
                    .attr('title', imei + ' — ' + (data.message || ''))
769
                    .text(icon + ' ' + short)
770
                    .appendTo($note);
771
            },
772
            error: function () {
773
                // Silently ignore — eligibility is a hint, not a blocker.
774
            }
775
        });
776
    });
777
});
778