Rev 37699 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<style>/* Availability shown against the quantity box when moving stock between our own warehouses. */.mv-qty-cell { position: relative; }.mv-qty-cell .qty { padding-right: 26px; }.mv-avail-icon {position: absolute; right: 6px; top: 50%; transform: translateY(-50%);width: 16px; height: 16px; line-height: 16px; border-radius: 50%;background: #5a6a7a; color: #fff; font-size: 11px; font-style: italic; font-weight: bold;text-align: center; cursor: pointer; user-select: none;}.mv-avail-icon.mv-part { background: #d58512; }.mv-avail-icon.mv-none { background: #c9302c; }.mv-qty-warn { color: #c9302c; font-size: 11px; margin-top: 2px; }.qty.mv-over { border-color: #c9302c; }/* Divs, not a table: Bootstrap's popover sanitizer drops table markup and everything inside it. */.popover .mv-avail { font-size: 12px; }.popover .mv-avail .mv-row { display: flex; justify-content: space-between; padding: 2px 0; }.popover .mv-avail .mv-val { padding-left: 12px; font-weight: bold; white-space: nowrap; }.popover .mv-avail .mv-po { padding-left: 10px; color: #777; }.popover .mv-avail .mv-po .mv-val { color: #777; font-weight: normal; }.popover .mv-avail .mv-total { border-top: 1px solid #ddd; margin-top: 2px; padding-top: 4px; }.popover .mv-note { margin-top: 6px; font-size: 11px; color: #777; }</style><div class="row"><div><p style="font-size: 25px;text-align: center; font-weight: bold; text-decoration-line: underline;">From $warehouse to $vendor.getName() </p></div></div><div class="row"><div class="col-lg-1 form-group"><input class="form-control btn btn-primary addRowInPurchaseOrder" type="button" value="Add Item"></div><div class="col-lg-2 form-group"><label class="btn btn-primary form-control" style="cursor:pointer;">Bulk Upload <input type="file" id="poItemsFile" accept=".xlsx,.xls" style="display:none;"></label></div><div class="col-lg-2 form-group"><a href="${rc.contextPath}/downloadPOItemsTemplate" class="btn btn-default form-control">Download Template</a></div></div><div class="row"><div class="col-lg-12"><table class="table table-border table-condensed table-bordered" id="purchase-order-table" style="width:100%"><thead><tr><th>Product Name</th><th>Qty</th><th>Transfer Price</th><th>Total Value</th></tr></thead><tbody></tbody></table></div></div><div class="row"><div class="col-md-12 form-group"><p><b><span>Total Quantity</span></b> -: <b><span id="totalQuantity"></span></b> <b><span>Grand Total</span></b> -: <b><span id="grandTotal"></span></b></p></div><div class="col-lg-2 form-group"><input class="form-control btn btn-primary createPurchaseOrder" type="button"value="Create and Save Purchase Order"></div><div class="col-lg-2 form-group"><input class="form-control btn btn-primary createSendPurchaseOrder" type="button"value="Create and Send Purchase Order"></div></div><script type="text/javascript">$('.addRowInPurchaseOrder').ready(function () {$('.addRowInPurchaseOrder').click();});</script><!-- ═════════════════════════════════════════════════════════════════════════════Create-PO modal stack — replaces native confirm/prompt. Three modals firein sequence: create-confirm → reason (only if approval needed) → approval-target confirm → actual create. All IDs are prefixed with `pmscp*` toavoid the global-jQuery delegated-handler collision problem.═════════════════════════════════════════════════════════════════════════════ --><style>.pmscp-modal .modal-dialog {margin-top: 80px}.pmscp-modal .modal-content {border-radius: 12px;border: 0;box-shadow: 0 20px 60px rgba(20, 40, 90, .18)}.pmscp-modal .modal-header {border-bottom: 1px solid #eef1f5;padding: 18px 24px 14px;display: flex;align-items: center;gap: 12px}.pmscp-modal .modal-header .pmscp-icon {width: 40px;height: 40px;border-radius: 50%;background: #eef2fb;color: #3b5bdb;display: inline-flex;align-items: center;justify-content: center;font-size: 20px}.pmscp-modal .modal-header h4 {margin: 0;font-size: 17px;font-weight: 700;color: #1f2c4f}.pmscp-modal .modal-header .pmscp-sub {display: block;font-size: 12px;color: #7b8199;font-weight: 500;margin-top: 3px}.pmscp-modal .modal-body {padding: 20px 24px;font-size: 13.5px;color: #2a3352}.pmscp-modal .modal-footer {border-top: 1px solid #eef1f5;padding: 14px 24px}.pmscp-modal .btn {padding: 8px 18px;border-radius: 8px;font-weight: 600;font-size: 13px}.pmscp-modal .btn-cancel {background: #f2f4f8;color: #4a5170;border: 1px solid #dfe3ec}.pmscp-modal .btn-primary-cta {background: #3b5bdb;color: #fff;border: 1px solid #3b5bdb}.pmscp-modal .btn-primary-cta:hover {background: #2f4bbf}.pmscp-modal .btn-primary-cta:disabled {opacity: .5;cursor: not-allowed}.pmscp-modal .btn-warn-cta {background: #b78600;color: #fff;border: 1px solid #b78600}.pmscp-modal .btn-warn-cta:disabled {opacity: .5;cursor: not-allowed}.pmscp-summary {background: #f7f9fd;border: 1px solid #e6ebf5;border-radius: 10px;padding: 14px 16px;margin-top: 10px}.pmscp-summary .pmscp-row {display: flex;justify-content: space-between;font-size: 13px;padding: 4px 0}.pmscp-summary .pmscp-row .pmscp-lbl {color: #7b8199}.pmscp-summary .pmscp-row .pmscp-val {color: #1f2c4f;font-weight: 600}.pmscp-warn {background: #fff8e1;border: 1px solid #f1e0b0;border-left: 4px solid #b78600;color: #8a6d3b;padding: 12px 14px;border-radius: 8px;font-size: 12.5px;line-height: 1.5;margin-bottom: 14px}.pmscp-warn b {color: #6a5220}#pmscpReasonText {width: 100%;min-height: 120px;border: 1px solid #dfe3ec;border-radius: 8px;padding: 10px 12px;font-size: 13.5px;font-family: inherit;resize: vertical;outline: none;transition: border-color .12s}#pmscpReasonText:focus {border-color: #3b5bdb;box-shadow: 0 0 0 3px rgba(59, 91, 219, .12)}.pmscp-counter {font-size: 11.5px;color: #7b8199;margin-top: 6px;display: flex;gap: 8px;align-items: center}.pmscp-counter #pmscpReasonCount {font-weight: 700;color: #c62828}.pmscp-counter.pmscp-ok #pmscpReasonCount {color: #177a3a}.pmscp-counter .pmscp-short {color: #c62828;font-style: italic}.pmscp-counter.pmscp-ok .pmscp-short {display: none}.pmscp-counter.pmscp-ok::after {content: "✓ ready";color: #177a3a;font-weight: 600}.pmscp-approver {display: flex;gap: 14px;align-items: center;background: #f7f9fd;border: 1px solid #e6ebf5;border-radius: 10px;padding: 14px 16px;margin-bottom: 14px}.pmscp-approver .pmscp-avatar {width: 52px;height: 52px;border-radius: 50%;background: #3b5bdb;color: #fff;font-weight: 700;font-size: 18px;display: inline-flex;align-items: center;justify-content: center;flex-shrink: 0}.pmscp-approver .pmscp-name {font-size: 15px;font-weight: 700;color: #1f2c4f}.pmscp-approver .pmscp-role {display: inline-block;margin-left: 8px;background: #eef2fb;color: #3b5bdb;font-size: 11px;font-weight: 700;padding: 2px 8px;border-radius: 10px;vertical-align: middle}.pmscp-approver .pmscp-mail {font-size: 12px;color: #7b8199;margin-top: 2px}.pmscp-reason-preview {background: #f2f4f8;border-radius: 8px;padding: 10px 12px;font-size: 12.5px;color: #4a5170;font-style: italic;max-height: 80px;overflow-y: auto;line-height: 1.5;white-space: pre-wrap}</style><!-- Modal 1 — Create-PO confirmation (shown before any server call). --><div class="modal pmscp-modal" id="pmscpConfirmModal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><span class="pmscp-icon">📄</span><div><h4>Create Purchase Order?</h4><span class="pmscp-sub">Please confirm the details below.</span></div></div><div class="modal-body"><div>You are about to create a purchase order with the following details:</div><div class="pmscp-summary"><div class="pmscp-row"><span class="pmscp-lbl">Vendor</span><span class="pmscp-val"id="pmscpSumVendor">—</span></div><div class="pmscp-row"><span class="pmscp-lbl">Warehouse</span><span class="pmscp-val"id="pmscpSumWarehouse">—</span></div><div class="pmscp-row"><span class="pmscp-lbl">Items</span><span class="pmscp-val"id="pmscpSumItems">—</span></div><div class="pmscp-row"><span class="pmscp-lbl">Total Qty</span><span class="pmscp-val"id="pmscpSumQty">—</span></div><div class="pmscp-row"><span class="pmscp-lbl">Grand Total</span><span class="pmscp-val"id="pmscpSumTotal">—</span></div></div></div><div class="modal-footer"><button type="button" class="btn btn-cancel" data-dismiss="modal">Cancel</button><button type="button" class="btn btn-primary-cta" id="pmscpConfirmCreate">Yes, Create PO</button></div></div></div></div><!-- Modal 2 — Reason for aging-stock purchase (with live 50-char counter). --><div class="modal pmscp-modal" id="pmscpReasonModal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><span class="pmscp-icon" style="background:#fff3d6;color:#b78600">⚠</span><div><h4>Approval Required — Reason Needed</h4><span class="pmscp-sub">This PO exceeds the 15-day stock cover rule.</span></div></div><div class="modal-body"><div class="pmscp-warn"><b>Why this PO needs approval:</b> Existing aging stock + this PO qty exceeds the last 15 days ofsales at the warehouse. It will be held for review by <b>Niranjan Kala</b> before being sent to thevendor.</div><!-- Flagged items table — populated by JS from preflight.flaggedItems.Shows only the SKUs that tripped the rule (mixed POs may have cleanitems too, which are not shown here). Helps the requester write aspecific reason rather than a generic one. --><div id="pmscpFlaggedBox" style="margin-bottom:14px;display:none"><div style="font-size:12px;font-weight:600;color:#4a5170;margin-bottom:6px">Items requiring approval (<span id="pmscpFlaggedCount">0</span>)</div><table style="width:100%;border-collapse:collapse;font-size:12px;border:1px solid #e6ebf5;border-radius:6px;overflow:hidden"><thead><tr style="background:#f7f9fd;color:#4a5170"><th style="text-align:left;padding:6px 10px;border-bottom:1px solid #e6ebf5">Item</th><th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">AgingStock<br/><span style="font-weight:normal;color:#7b8199;font-size:10px">vendor + warehouse</span></th><th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">15dSold<br/><span style="font-weight:normal;color:#7b8199;font-size:10px">warehouse</span></th><th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">PO Qty</th><th style="text-align:right;padding:6px 10px;border-bottom:1px solid #e6ebf5">Excess</th></tr></thead><tbody id="pmscpFlaggedRows"></tbody></table></div><label for="pmscpReasonText"style="display:block;font-size:12px;font-weight:600;color:#4a5170;margin-bottom:6px">Please explain why this aging stock is required (minimum 50 characters)</label><textarea id="pmscpReasonText"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><div class="pmscp-counter" id="pmscpReasonCounter"><span id="pmscpReasonCount">0</span> / 50 characters minimum<span class="pmscp-short">— need more detail</span></div></div><div class="modal-footer"><button type="button" class="btn btn-cancel" data-dismiss="modal">Cancel</button><button type="button" class="btn btn-warn-cta" id="pmscpReasonContinue" disabled>Continue →</button></div></div></div></div><!-- Modal 3 — Final "sending for approval to X" confirmation. --><div class="modal pmscp-modal" id="pmscpApprovalModal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><span class="pmscp-icon" style="background:#e6f4ea;color:#177a3a">✓</span><div><h4>Send for Approval</h4><span class="pmscp-sub">Confirm the PO will be held for approval.</span></div></div><div class="modal-body"><div class="pmscp-approver"><div class="pmscp-avatar">NK</div><div><div><span class="pmscp-name">Niranjan Kala</span><span class="pmscp-role">Category · L4</span></div><div class="pmscp-mail">niranjan.kala@smartdukaan.com</div></div></div><div style="font-size:12px;font-weight:600;color:#4a5170;margin-bottom:6px">Your reason (will be visibleto Niranjan)</div><div class="pmscp-reason-preview" id="pmscpApprovalReasonPreview">—</div><div style="margin-top:14px;font-size:12.5px;color:#5a6082;line-height:1.5">By clicking <b>Confirm & Send</b>, this PO will be created in a held state. Niranjan will benotified by email and can approve or reject it from the Stock Approvals queue. You will not need tore-create the PO — approval will release it automatically.</div></div><div class="modal-footer"><button type="button" class="btn btn-cancel" id="pmscpApprovalBack">← Back</button><button type="button" class="btn btn-primary-cta" id="pmscpApprovalConfirm">Confirm & Send forApproval</button></div></div></div></div>