Subversion Repositories SmartDukaan

Rev

Rev 37699 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37699 Rev 37750
Line 89... Line 89...
89
 
89
 
90
<script type="text/javascript">
90
<script type="text/javascript">
91
    $('.addRowInPurchaseOrder').ready(function () {
91
    $('.addRowInPurchaseOrder').ready(function () {
92
        $('.addRowInPurchaseOrder').click();
92
        $('.addRowInPurchaseOrder').click();
93
    });
93
    });
94
</script>
-
 
95
94
</script>
-
 
95
 
-
 
96
<!-- ═════════════════════════════════════════════════════════════════════════════
-
 
97
     Create-PO modal stack — replaces native confirm/prompt. Three modals fire
-
 
98
     in sequence: create-confirm → reason (only if approval needed) → approval-
-
 
99
     target confirm → actual create. All IDs are prefixed with `pmscp*` to
-
 
100
     avoid the global-jQuery delegated-handler collision problem.
-
 
101
     ═════════════════════════════════════════════════════════════════════════════ -->
-
 
102
 
-
 
103
<style>
-
 
104
    .pmscp-modal .modal-dialog {
-
 
105
        margin-top: 80px
-
 
106
    }
-
 
107
 
-
 
108
    .pmscp-modal .modal-content {
-
 
109
        border-radius: 12px;
-
 
110
        border: 0;
-
 
111
        box-shadow: 0 20px 60px rgba(20, 40, 90, .18)
-
 
112
    }
-
 
113
 
-
 
114
    .pmscp-modal .modal-header {
-
 
115
        border-bottom: 1px solid #eef1f5;
-
 
116
        padding: 18px 24px 14px;
-
 
117
        display: flex;
-
 
118
        align-items: center;
-
 
119
        gap: 12px
-
 
120
    }
-
 
121
 
-
 
122
    .pmscp-modal .modal-header .pmscp-icon {
-
 
123
        width: 40px;
-
 
124
        height: 40px;
-
 
125
        border-radius: 50%;
-
 
126
        background: #eef2fb;
-
 
127
        color: #3b5bdb;
-
 
128
        display: inline-flex;
-
 
129
        align-items: center;
-
 
130
        justify-content: center;
-
 
131
        font-size: 20px
-
 
132
    }
-
 
133
 
-
 
134
    .pmscp-modal .modal-header h4 {
-
 
135
        margin: 0;
-
 
136
        font-size: 17px;
-
 
137
        font-weight: 700;
-
 
138
        color: #1f2c4f
-
 
139
    }
-
 
140
 
-
 
141
    .pmscp-modal .modal-header .pmscp-sub {
-
 
142
        display: block;
-
 
143
        font-size: 12px;
-
 
144
        color: #7b8199;
-
 
145
        font-weight: 500;
-
 
146
        margin-top: 3px
-
 
147
    }
-
 
148
 
-
 
149
    .pmscp-modal .modal-body {
-
 
150
        padding: 20px 24px;
-
 
151
        font-size: 13.5px;
-
 
152
        color: #2a3352
-
 
153
    }
-
 
154
 
-
 
155
    .pmscp-modal .modal-footer {
-
 
156
        border-top: 1px solid #eef1f5;
-
 
157
        padding: 14px 24px
-
 
158
    }
-
 
159
 
-
 
160
    .pmscp-modal .btn {
-
 
161
        padding: 8px 18px;
-
 
162
        border-radius: 8px;
-
 
163
        font-weight: 600;
-
 
164
        font-size: 13px
-
 
165
    }
-
 
166
 
-
 
167
    .pmscp-modal .btn-cancel {
-
 
168
        background: #f2f4f8;
-
 
169
        color: #4a5170;
-
 
170
        border: 1px solid #dfe3ec
-
 
171
    }
-
 
172
 
-
 
173
    .pmscp-modal .btn-primary-cta {
-
 
174
        background: #3b5bdb;
-
 
175
        color: #fff;
-
 
176
        border: 1px solid #3b5bdb
-
 
177
    }
-
 
178
 
-
 
179
    .pmscp-modal .btn-primary-cta:hover {
-
 
180
        background: #2f4bbf
-
 
181
    }
-
 
182
 
-
 
183
    .pmscp-modal .btn-primary-cta:disabled {
-
 
184
        opacity: .5;
-
 
185
        cursor: not-allowed
-
 
186
    }
-
 
187
 
-
 
188
    .pmscp-modal .btn-warn-cta {
-
 
189
        background: #b78600;
-
 
190
        color: #fff;
-
 
191
        border: 1px solid #b78600
-
 
192
    }
-
 
193
 
-
 
194
    .pmscp-modal .btn-warn-cta:disabled {
-
 
195
        opacity: .5;
-
 
196
        cursor: not-allowed
-
 
197
    }
-
 
198
 
-
 
199
    .pmscp-summary {
-
 
200
        background: #f7f9fd;
-
 
201
        border: 1px solid #e6ebf5;
-
 
202
        border-radius: 10px;
-
 
203
        padding: 14px 16px;
-
 
204
        margin-top: 10px
-
 
205
    }
-
 
206
 
-
 
207
    .pmscp-summary .pmscp-row {
-
 
208
        display: flex;
-
 
209
        justify-content: space-between;
-
 
210
        font-size: 13px;
-
 
211
        padding: 4px 0
-
 
212
    }
-
 
213
 
-
 
214
    .pmscp-summary .pmscp-row .pmscp-lbl {
-
 
215
        color: #7b8199
-
 
216
    }
-
 
217
 
-
 
218
    .pmscp-summary .pmscp-row .pmscp-val {
-
 
219
        color: #1f2c4f;
-
 
220
        font-weight: 600
-
 
221
    }
-
 
222
 
-
 
223
    .pmscp-warn {
-
 
224
        background: #fff8e1;
-
 
225
        border: 1px solid #f1e0b0;
-
 
226
        border-left: 4px solid #b78600;
-
 
227
        color: #8a6d3b;
-
 
228
        padding: 12px 14px;
-
 
229
        border-radius: 8px;
-
 
230
        font-size: 12.5px;
-
 
231
        line-height: 1.5;
-
 
232
        margin-bottom: 14px
-
 
233
    }
-
 
234
 
-
 
235
    .pmscp-warn b {
-
 
236
        color: #6a5220
-
 
237
    }
-
 
238
 
-
 
239
    #pmscpReasonText {
-
 
240
        width: 100%;
-
 
241
        min-height: 120px;
-
 
242
        border: 1px solid #dfe3ec;
-
 
243
        border-radius: 8px;
-
 
244
        padding: 10px 12px;
-
 
245
        font-size: 13.5px;
-
 
246
        font-family: inherit;
-
 
247
        resize: vertical;
-
 
248
        outline: none;
-
 
249
        transition: border-color .12s
-
 
250
    }
-
 
251
 
-
 
252
    #pmscpReasonText:focus {
-
 
253
        border-color: #3b5bdb;
-
 
254
        box-shadow: 0 0 0 3px rgba(59, 91, 219, .12)
-
 
255
    }
-
 
256
 
-
 
257
    .pmscp-counter {
-
 
258
        font-size: 11.5px;
-
 
259
        color: #7b8199;
-
 
260
        margin-top: 6px;
-
 
261
        display: flex;
-
 
262
        gap: 8px;
-
 
263
        align-items: center
-
 
264
    }
-
 
265
 
-
 
266
    .pmscp-counter #pmscpReasonCount {
-
 
267
        font-weight: 700;
-
 
268
        color: #c62828
-
 
269
    }
-
 
270
 
-
 
271
    .pmscp-counter.pmscp-ok #pmscpReasonCount {
-
 
272
        color: #177a3a
-
 
273
    }
-
 
274
 
-
 
275
    .pmscp-counter .pmscp-short {
-
 
276
        color: #c62828;
-
 
277
        font-style: italic
-
 
278
    }
-
 
279
 
-
 
280
    .pmscp-counter.pmscp-ok .pmscp-short {
-
 
281
        display: none
-
 
282
    }
-
 
283
 
-
 
284
    .pmscp-counter.pmscp-ok::after {
-
 
285
        content: "✓ ready";
-
 
286
        color: #177a3a;
-
 
287
        font-weight: 600
-
 
288
    }
-
 
289
 
-
 
290
    .pmscp-approver {
-
 
291
        display: flex;
-
 
292
        gap: 14px;
-
 
293
        align-items: center;
-
 
294
        background: #f7f9fd;
-
 
295
        border: 1px solid #e6ebf5;
-
 
296
        border-radius: 10px;
-
 
297
        padding: 14px 16px;
-
 
298
        margin-bottom: 14px
-
 
299
    }
-
 
300
 
-
 
301
    .pmscp-approver .pmscp-avatar {
-
 
302
        width: 52px;
-
 
303
        height: 52px;
-
 
304
        border-radius: 50%;
-
 
305
        background: #3b5bdb;
-
 
306
        color: #fff;
-
 
307
        font-weight: 700;
-
 
308
        font-size: 18px;
-
 
309
        display: inline-flex;
-
 
310
        align-items: center;
-
 
311
        justify-content: center;
-
 
312
        flex-shrink: 0
-
 
313
    }
-
 
314
 
-
 
315
    .pmscp-approver .pmscp-name {
-
 
316
        font-size: 15px;
-
 
317
        font-weight: 700;
-
 
318
        color: #1f2c4f
-
 
319
    }
-
 
320
 
-
 
321
    .pmscp-approver .pmscp-role {
-
 
322
        display: inline-block;
-
 
323
        margin-left: 8px;
-
 
324
        background: #eef2fb;
-
 
325
        color: #3b5bdb;
-
 
326
        font-size: 11px;
-
 
327
        font-weight: 700;
-
 
328
        padding: 2px 8px;
-
 
329
        border-radius: 10px;
-
 
330
        vertical-align: middle
-
 
331
    }
-
 
332
 
-
 
333
    .pmscp-approver .pmscp-mail {
-
 
334
        font-size: 12px;
-
 
335
        color: #7b8199;
-
 
336
        margin-top: 2px
-
 
337
    }
-
 
338
 
-
 
339
    .pmscp-reason-preview {
-
 
340
        background: #f2f4f8;
-
 
341
        border-radius: 8px;
-
 
342
        padding: 10px 12px;
-
 
343
        font-size: 12.5px;
-
 
344
        color: #4a5170;
-
 
345
        font-style: italic;
-
 
346
        max-height: 80px;
-
 
347
        overflow-y: auto;
-
 
348
        line-height: 1.5;
-
 
349
        white-space: pre-wrap
-
 
350
    }
-
 
351
</style>
-
 
352
 
-
 
353
<!-- Modal 1 — Create-PO confirmation (shown before any server call). -->
-
 
354
<div class="modal pmscp-modal" id="pmscpConfirmModal" tabindex="-1" role="dialog" aria-hidden="true">
-
 
355
    <div class="modal-dialog" role="document">
-
 
356
        <div class="modal-content">
-
 
357
            <div class="modal-header">
-
 
358
                <span class="pmscp-icon">📄</span>
-
 
359
                <div>
-
 
360
                    <h4>Create Purchase Order?</h4>
-
 
361
                    <span class="pmscp-sub">Please confirm the details below.</span>
-
 
362
                </div>
-
 
363
            </div>
-
 
364
            <div class="modal-body">
-
 
365
                <div>You are about to create a purchase order with the following details:</div>
-
 
366
                <div class="pmscp-summary">
-
 
367
                    <div class="pmscp-row"><span class="pmscp-lbl">Vendor</span><span class="pmscp-val"
-
 
368
                                                                                      id="pmscpSumVendor">—</span></div>
-
 
369
                    <div class="pmscp-row"><span class="pmscp-lbl">Warehouse</span><span class="pmscp-val"
-
 
370
                                                                                         id="pmscpSumWarehouse">—</span>
-
 
371
                    </div>
-
 
372
                    <div class="pmscp-row"><span class="pmscp-lbl">Items</span><span class="pmscp-val"
-
 
373
                                                                                     id="pmscpSumItems">—</span></div>
-
 
374
                    <div class="pmscp-row"><span class="pmscp-lbl">Total Qty</span><span class="pmscp-val"
-
 
375
                                                                                         id="pmscpSumQty">—</span></div>
-
 
376
                    <div class="pmscp-row"><span class="pmscp-lbl">Grand Total</span><span class="pmscp-val"
-
 
377
                                                                                           id="pmscpSumTotal">—</span>
-
 
378
                    </div>
-
 
379
                </div>
-
 
380
            </div>
-
 
381
            <div class="modal-footer">
-
 
382
                <button type="button" class="btn btn-cancel" data-dismiss="modal">Cancel</button>
-
 
383
                <button type="button" class="btn btn-primary-cta" id="pmscpConfirmCreate">Yes, Create PO</button>
-
 
384
            </div>
-
 
385
        </div>
-
 
386
    </div>
-
 
387
</div>
-
 
388
 
-
 
389
<!-- Modal 2 — Reason for aging-stock purchase (with live 50-char counter). -->
-
 
390
<div class="modal pmscp-modal" id="pmscpReasonModal" tabindex="-1" role="dialog" aria-hidden="true">
-
 
391
    <div class="modal-dialog" role="document">
-
 
392
        <div class="modal-content">
-
 
393
            <div class="modal-header">
-
 
394
                <span class="pmscp-icon" style="background:#fff3d6;color:#b78600">⚠</span>
-
 
395
                <div>
-
 
396
                    <h4>Approval Required — Reason Needed</h4>
-
 
397
                    <span class="pmscp-sub">This PO exceeds the 15-day stock cover rule.</span>
-
 
398
                </div>
-
 
399
            </div>
-
 
400
            <div class="modal-body">
-
 
401
                <div class="pmscp-warn">
-
 
402
                    <b>Why this PO needs approval:</b> Existing aging stock + this PO qty exceeds the last 15 days of
-
 
403
                    sales at the warehouse. It will be held for review by <b>Niranjan Kala</b> before being sent to the
-
 
404
                    vendor.
-
 
405
                </div>
-
 
406
 
-
 
407
                <!-- Flagged items table — populated by JS from preflight.flaggedItems.
-
 
408
                     Shows only the SKUs that tripped the rule (mixed POs may have clean
-
 
409
                     items too, which are not shown here). Helps the requester write a
-
 
410
                     specific reason rather than a generic one. -->
-
 
411
                <div id="pmscpFlaggedBox" style="margin-bottom:14px;display:none">
-
 
412
                    <div style="font-size:12px;font-weight:600;color:#4a5170;margin-bottom:6px">
-
 
413
                        Items requiring approval (<span id="pmscpFlaggedCount">0</span>)
-
 
414
                    </div>
-
 
415
                    <table style="width:100%;border-collapse:collapse;font-size:12px;border:1px solid #e6ebf5;border-radius:6px;overflow:hidden">
-
 
416
                        <thead>
-
 
417
                        <tr style="background:#f7f9fd;color:#4a5170">
-
 
418
                            <th style="text-align:left;padding:6px 10px;border-bottom:1px solid #e6ebf5">Item</th>
-
 
419
                            <th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">Aging
-
 
420
                                Stock<br/><span style="font-weight:normal;color:#7b8199;font-size:10px">vendor + warehouse</span>
-
 
421
                            </th>
-
 
422
                            <th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">15d
-
 
423
                                Sold<br/><span style="font-weight:normal;color:#7b8199;font-size:10px">warehouse</span>
-
 
424
                            </th>
-
 
425
                            <th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">PO Qty</th>
-
 
426
                            <th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">Excess</th>
-
 
427
                        </tr>
-
 
428
                        </thead>
-
 
429
                        <tbody id="pmscpFlaggedRows"></tbody>
-
 
430
                    </table>
-
 
431
                </div>
-
 
432
 
-
 
433
                <label for="pmscpReasonText"
-
 
434
                       style="display:block;font-size:12px;font-weight:600;color:#4a5170;margin-bottom:6px">
-
 
435
                    Please explain why this aging stock is required (minimum 50 characters)
-
 
436
                </label>
-
 
437
                <textarea id="pmscpReasonText"
-
 
438
                          placeholder="e.g. Vendor closing brand; must clear last-shot inventory. Or: Focused push for this SKU next 30 days per Manish. Be specific enough for Niranjan to decide."></textarea>
-
 
439
                <div class="pmscp-counter" id="pmscpReasonCounter">
-
 
440
                    <span id="pmscpReasonCount">0</span> / 50 characters minimum
-
 
441
                    <span class="pmscp-short">— need more detail</span>
-
 
442
                </div>
-
 
443
            </div>
-
 
444
            <div class="modal-footer">
-
 
445
                <button type="button" class="btn btn-cancel" data-dismiss="modal">Cancel</button>
-
 
446
                <button type="button" class="btn btn-warn-cta" id="pmscpReasonContinue" disabled>Continue &rarr;
-
 
447
                </button>
-
 
448
            </div>
-
 
449
        </div>
-
 
450
    </div>
-
 
451
</div>
-
 
452
 
-
 
453
<!-- Modal 3 — Final "sending for approval to X" confirmation. -->
-
 
454
<div class="modal pmscp-modal" id="pmscpApprovalModal" tabindex="-1" role="dialog" aria-hidden="true">
-
 
455
    <div class="modal-dialog" role="document">
-
 
456
        <div class="modal-content">
-
 
457
            <div class="modal-header">
-
 
458
                <span class="pmscp-icon" style="background:#e6f4ea;color:#177a3a">✓</span>
-
 
459
                <div>
-
 
460
                    <h4>Send for Approval</h4>
-
 
461
                    <span class="pmscp-sub">Confirm the PO will be held for approval.</span>
-
 
462
                </div>
-
 
463
            </div>
-
 
464
            <div class="modal-body">
-
 
465
                <div class="pmscp-approver">
-
 
466
                    <div class="pmscp-avatar">NK</div>
-
 
467
                    <div>
-
 
468
                        <div>
-
 
469
                            <span class="pmscp-name">Niranjan Kala</span>
-
 
470
                            <span class="pmscp-role">Category · L4</span>
-
 
471
                        </div>
-
 
472
                        <div class="pmscp-mail">niranjan.kala@smartdukaan.com</div>
-
 
473
                    </div>
-
 
474
                </div>
-
 
475
                <div style="font-size:12px;font-weight:600;color:#4a5170;margin-bottom:6px">Your reason (will be visible
-
 
476
                    to Niranjan)
-
 
477
                </div>
-
 
478
                <div class="pmscp-reason-preview" id="pmscpApprovalReasonPreview">—</div>
-
 
479
                <div style="margin-top:14px;font-size:12.5px;color:#5a6082;line-height:1.5">
-
 
480
                    By clicking <b>Confirm &amp; Send</b>, this PO will be created in a held state. Niranjan will be
-
 
481
                    notified by email and can approve or reject it from the Stock Approvals queue. You will not need to
-
 
482
                    re-create the PO — approval will release it automatically.
-
 
483
                </div>
-
 
484
            </div>
-
 
485
            <div class="modal-footer">
-
 
486
                <button type="button" class="btn btn-cancel" id="pmscpApprovalBack">&larr; Back</button>
-
 
487
                <button type="button" class="btn btn-primary-cta" id="pmscpApprovalConfirm">Confirm &amp; Send for
-
 
488
                    Approval
-
 
489
                </button>
-
 
490
            </div>
-
 
491
        </div>
-
 
492
    </div>
-
 
493
</div>
-
 
494
96
495