HEX
Server: Microsoft-IIS/10.0
System: Windows NT ITPWINWEBSVR22 10.0 build 20348 (Windows Server 2022) AMD64
User: www.conferencesearch.co.uk (0)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: D:/web/hyperflight/apps/stockflow/index-v10.asp
<%
Option Explicit
Response.Buffer = True ' Ensure buffering is on so we can manually Flush it later

' ======================================================================
' 0. AJAX Endpoint for Incremental Search (Auto-suggest)
' ======================================================================
If Request.QueryString("action") = "search" Then
    Dim searchQuery, searchConn, searchCmd, searchRs, jsonStr, isFirst
    Dim safeCode, safeName
    searchQuery = Trim(Request.QueryString("q"))
    Response.ContentType = "application/json"
    
    If Len(searchQuery) > 1 Then
        Set searchConn = Server.CreateObject("ADODB.Connection")
        searchConn.Open "DSN=MySQL_hyperflight;"
        Set searchCmd = Server.CreateObject("ADODB.Command")
        Set searchCmd.ActiveConnection = searchConn
        searchCmd.CommandType = 1 ' adCmdText
        
        ' Filter by ProductDisabled = 0 and select both Code and Name
        searchCmd.CommandText = "SELECT ProductCode, ProductName FROM products WHERE ProductCode LIKE ? AND ProductDisabled = 0 ORDER BY ProductCode ASC LIMIT 15"
        searchCmd.Parameters.Append searchCmd.CreateParameter("@q", 200, 1, 100, "%" & searchQuery & "%") 
        
        Set searchRs = searchCmd.Execute()
        
        jsonStr = "["
        isFirst = True
        Do While Not searchRs.EOF
            If Not isFirst Then jsonStr = jsonStr & ","
            
            ' Safely escape quotes and backslashes for JSON formatting
            safeCode = Replace(Replace(searchRs("ProductCode") & "", "\", "\\"), """", "\""")
            safeName = Replace(Replace(searchRs("ProductName") & "", "\", "\\"), """", "\""")
            
            ' Output as an object: {"c": "Code", "n": "Name"}
            jsonStr = jsonStr & "{""c"":""" & safeCode & """, ""n"":""" & safeName & """}"
            
            isFirst = False
            searchRs.MoveNext
        Loop
        jsonStr = jsonStr & "]"
        
        Response.Write jsonStr
        searchRs.Close
        Set searchRs = Nothing
        Set searchCmd = Nothing
        searchConn.Close
        Set searchConn = Nothing
    Else
        Response.Write "[]"
    End If
    Response.End 
End If
' ======================================================================


' ADO Constants for Parameterized Queries
Const adCmdText = 1
Const adParamInput = 1
Const adVarChar = 200
Const adInteger = 3

Dim productCode, conn, cmd, rs, rsSnap
Dim productID, recordedNumInStock, currentCalculatedStock, discrepancy
Dim productName 
Dim transactionDate, transType, qty, ref, status, prevStockSys, stockAfterSys
Dim isMatchedOrder, isMatchedInvoice, isDuplicate, showRow
Dim startingStockInput, startingStock, startDate, snapshotInfo
Dim auditVisibility, auditSync
Dim sqlOrders, sqlInvoices, sqlAudit, finalSql
Dim displayQty, cssClass, rowClass, syncBadge
Dim rowCount ' For the flush buffer

' Initialize variables from form submission
productCode = UCase(Trim(Request.Form("ProductCode")))
startingStockInput = Trim(Request.Form("StartingStock"))
startDate = Trim(Request.Form("StartDate"))
auditVisibility = Request.Form("AuditVisibility")
auditSync = Request.Form("AuditSync")

' Set defaults for first load
If auditVisibility = "" Then auditVisibility = "3" ' Default to Clean View
If auditSync = "" Then auditSync = "0" ' Default to Display Only

productID = 0
recordedNumInStock = 0
startingStock = 0
snapshotInfo = "Manual Baseline (or 0 if blank)"
productName = ""

If productCode <> "" Then
    Set conn = Server.CreateObject("ADODB.Connection")
    conn.Open "DSN=MySQL_hyperflight;"

    ' 1. Get ProductID, Current System Stock, and Name
    Set cmd = Server.CreateObject("ADODB.Command")
    Set cmd.ActiveConnection = conn
    cmd.CommandType = adCmdText
    cmd.CommandText = "SELECT ProductID, NumInStock, ProductName FROM products WHERE ProductCode = ?"
    cmd.Parameters.Append cmd.CreateParameter("@ProdCode", adVarChar, adParamInput, 20, productCode)
    
    Set rs = cmd.Execute()
    If Not rs.EOF Then
        productID = rs("ProductID")
        If Not IsNull(rs("NumInStock")) Then recordedNumInStock = CLng(rs("NumInStock"))
        If Not IsNull(rs("ProductName")) Then productName = rs("ProductName")
    End If
    rs.Close
    Set cmd = Nothing

    ' 2. Auto-fetch Starting Stock from Snapshots
    If productID > 0 Then
        If startingStockInput <> "" And IsNumeric(startingStockInput) Then
            startingStock = CLng(startingStockInput)
            snapshotInfo = "Manual Input"
        ElseIf startDate <> "" Then
            Set cmd = Server.CreateObject("ADODB.Command")
            Set cmd.ActiveConnection = conn
            cmd.CommandType = adCmdText
            cmd.CommandText = "SELECT NumInStock, DateOfStock, TimeOfStock FROM stock_snapshots WHERE ProductID = ? AND DateOfStock < ? ORDER BY DateOfStock DESC LIMIT 1"
            cmd.Parameters.Append cmd.CreateParameter("@ProdID", adInteger, adParamInput, , productID)
            cmd.Parameters.Append cmd.CreateParameter("@SnapDate", adVarChar, adParamInput, 20, startDate)
            
            Set rsSnap = cmd.Execute()
            If Not rsSnap.EOF Then
                If Not IsNull(rsSnap("NumInStock")) Then startingStock = CLng(rsSnap("NumInStock"))
                snapshotInfo = "Auto-Snapshot from " & rsSnap("DateOfStock")
            Else
                snapshotInfo = "No prior snapshot found. Defaulting to 0."
            End If
            rsSnap.Close
            Set cmd = Nothing
        End If
    End If

    currentCalculatedStock = startingStock 

    ' 3. Dynamic Query Builder with Fuzzy Matching Flags & Sort Priority
    If productID > 0 Then
        Set cmd = Server.CreateObject("ADODB.Command")
        Set cmd.ActiveConnection = conn
        cmd.CommandType = adCmdText
        
        ' Base Queries (SortPriority 1 for human actions)
        sqlOrders = "SELECT o.DateTimeOrdered AS TransDate, 'OUT' AS TransType, od.Qty AS Amount, CAST(o.OrderNo AS VARCHAR(50)) AS Ref, o.Status, od.PrevStock AS PrevStockSys, NULL AS StockAfterSys, 0 AS IsMatchedOrder, 0 AS IsMatchedInvoice, 1 AS SortPriority " & _
                    "FROM orders o " & _
                    "INNER JOIN orderdetails od ON o.OrderNo = od.OrderNo " & _
                    "WHERE od.ProductID = ? " & _
                    "AND o.Status IN ('COMPLETED', 'PAYMENT RECEIVED', 'AWAITING PAYMENT', 'PAYMENT ON ACCOUNT') " & _
                    "AND o.IsInvoice = 1 "
                    
        sqlInvoices = "SELECT CAST(pi.InvoiceDate AS DATETIME) AS TransDate, 'IN' AS TransType, pil.QtyAddedToStock AS Amount, CAST(pi.PurchaseInvoiceID AS VARCHAR(50)) AS Ref, pi.InvoiceStatus AS Status, NULL AS PrevStockSys, NULL AS StockAfterSys, 0 AS IsMatchedOrder, 0 AS IsMatchedInvoice, 1 AS SortPriority " & _
                      "FROM purchase_invoices pi " & _
                      "INNER JOIN purchase_invoice_lines pil ON pi.PurchaseInvoiceID = pil.PurchaseInvoiceID " & _
                      "INNER JOIN purchase_order_lines pol ON pil.PurchaseOrderLineID = pol.PurchaseOrderLineID " & _
                      "WHERE pol.ProductID = ? "
                      
        ' Audit Query (SortPriority 2 for database triggers)
        sqlAudit = "SELECT sa.DateTimeUpdated AS TransDate, 'ADJ' AS TransType, (sa.StockAfter - sa.StockBefore) AS Amount, sa.UserName AS Ref, sa.PCName AS Status, sa.StockBefore AS PrevStockSys, sa.StockAfter AS StockAfterSys, " & _
                   "IFNULL((SELECT 1 FROM orders o INNER JOIN orderdetails od ON o.OrderNo = od.OrderNo WHERE od.ProductID = sa.ProductID AND -od.Qty = (sa.StockAfter - sa.StockBefore) AND o.IsInvoice = 1 AND o.Status IN ('COMPLETED', 'PAYMENT RECEIVED', 'AWAITING PAYMENT', 'PAYMENT ON ACCOUNT') AND o.DateTimeOrdered BETWEEN sa.DateTimeUpdated - INTERVAL 2 MINUTE AND sa.DateTimeUpdated + INTERVAL 2 MINUTE LIMIT 1), 0) AS IsMatchedOrder, " & _
                   "IFNULL((SELECT 1 FROM purchase_invoice_lines pil INNER JOIN purchase_invoices pi ON pil.PurchaseInvoiceID = pi.PurchaseInvoiceID INNER JOIN purchase_order_lines pol ON pil.PurchaseOrderLineID = pol.PurchaseOrderLineID WHERE pol.ProductID = sa.ProductID AND pil.QtyAddedToStock = (sa.StockAfter - sa.StockBefore) AND pi.InvoiceDate BETWEEN sa.DateTimeUpdated - INTERVAL 60 DAY AND sa.DateTimeUpdated + INTERVAL 1 DAY LIMIT 1), 0) AS IsMatchedInvoice, " & _
                   "2 AS SortPriority " & _
                   "FROM stock_audit sa " & _
                   "WHERE sa.ProductID = ? AND sa.AuditType = 'Main' "
                   
        If auditVisibility = "1" Then
            sqlAudit = sqlAudit & " AND IFNULL(sa.PCName, '') <> '-WEBSITE-' "
        End If

        ' Apply Date Filters
        If startDate <> "" Then
            sqlOrders = sqlOrders & " AND o.DateTimeOrdered >= ? "
            sqlInvoices = sqlInvoices & " AND pi.InvoiceDate >= ? "
            sqlAudit = sqlAudit & " AND sa.DateTimeUpdated >= ? "
        End If

        ' Combine queries based on visibility selection
        If auditVisibility = "0" Then
            finalSql = sqlOrders & " UNION ALL " & sqlInvoices & " ORDER BY TransDate ASC, SortPriority ASC"
        ElseIf auditVisibility = "4" Then
            finalSql = sqlAudit & " ORDER BY TransDate ASC, SortPriority ASC"
        Else
            finalSql = sqlOrders & " UNION ALL " & sqlInvoices & " UNION ALL " & sqlAudit & " ORDER BY TransDate ASC, SortPriority ASC"
        End If
        
        cmd.CommandText = finalSql
        
        ' Append parameters sequentially
        If auditVisibility = "0" Then
            cmd.Parameters.Append cmd.CreateParameter("@ProdID1", adInteger, adParamInput, , productID)
            If startDate <> "" Then cmd.Parameters.Append cmd.CreateParameter("@StartDate1", adVarChar, adParamInput, 20, startDate & " 00:00:00")
            cmd.Parameters.Append cmd.CreateParameter("@ProdID2", adInteger, adParamInput, , productID)
            If startDate <> "" Then cmd.Parameters.Append cmd.CreateParameter("@StartDate2", adVarChar, adParamInput, 20, startDate)
        ElseIf auditVisibility = "4" Then
            cmd.Parameters.Append cmd.CreateParameter("@ProdID3", adInteger, adParamInput, , productID)
            If startDate <> "" Then cmd.Parameters.Append cmd.CreateParameter("@StartDate3", adVarChar, adParamInput, 20, startDate & " 00:00:00")
        Else
            cmd.Parameters.Append cmd.CreateParameter("@ProdID1", adInteger, adParamInput, , productID)
            If startDate <> "" Then cmd.Parameters.Append cmd.CreateParameter("@StartDate1", adVarChar, adParamInput, 20, startDate & " 00:00:00")
            cmd.Parameters.Append cmd.CreateParameter("@ProdID2", adInteger, adParamInput, , productID)
            If startDate <> "" Then cmd.Parameters.Append cmd.CreateParameter("@StartDate2", adVarChar, adParamInput, 20, startDate)
            cmd.Parameters.Append cmd.CreateParameter("@ProdID3", adInteger, adParamInput, , productID)
            If startDate <> "" Then cmd.Parameters.Append cmd.CreateParameter("@StartDate3", adVarChar, adParamInput, 20, startDate & " 00:00:00")
        End If

        Set rs = cmd.Execute()
    End If
End If
%>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Stock Flow Checker</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .table-responsive { max-width: 1200px; }
        .qty-in { color: #198754; font-weight: bold; } 
        .qty-out { color: #dc3545; font-weight: bold; }
        .qty-adj { color: #0dcaf0; font-weight: bold; }
        .drift-warning { background-color: #fff3cd !important; }
        .sync-row { background-color: #e2e3e5 !important; border-left: 4px solid #0d6efd; }
        .duplicate-row { opacity: 0.55; background-color: #f8f9fa !important; font-style: italic; }
        #ProductCode { text-transform: uppercase; }
        .product-header-img { max-width: 80px; max-height: 80px; object-fit: contain; border: 1px solid #dee2e6; padding: 4px; border-radius: 6px; background: #fff;}
    </style>
</head>
<body class="bg-light pb-5">

<div class="container mt-5">
    <div class="card shadow-sm mb-4" style="max-width: 1200px;">
        <div class="card-header bg-primary text-white">
            <h4 class="mb-0">Stock Flow Checker (Hybrid Mode)</h4>
        </div>
        <div class="card-body bg-light">
            <form method="post" action="" class="row g-3">
                <div class="col-md-3">
                    <label for="ProductCode" class="form-label fw-bold mb-1">Product Code:</label>
                    <input type="text" id="ProductCode" name="ProductCode" class="form-control" list="productCodes" autocomplete="off" placeholder="e.g. KST..." value="<%=Server.HTMLEncode(productCode)%>" required>
                    <datalist id="productCodes"></datalist>
                </div>
                <div class="col-md-3">
                    <label for="StartDate" class="form-label fw-bold mb-1">Start Date:</label>
                    <input type="date" id="StartDate" name="StartDate" class="form-control" value="<%=Server.HTMLEncode(startDate)%>">
                </div>
                <div class="col-md-2">
                    <label for="StartingStock" class="form-label fw-bold mb-1">Override Start:</label>
                    <input type="number" id="StartingStock" name="StartingStock" class="form-control" placeholder="Auto" value="<%=Server.HTMLEncode(startingStockInput)%>">
                </div>
                
                <div class="col-md-4 d-flex align-items-end">
                    <button type="submit" class="btn btn-primary w-100 fw-bold">Run Ledger</button>
                </div>

                <div class="col-md-4">
                    <label for="AuditVisibility" class="form-label fw-bold mb-1">Audit Trail Visibility:</label>
                    <select id="AuditVisibility" name="AuditVisibility" class="form-select">
                        <option value="0" <% If auditVisibility="0" Then Response.Write "selected" %>>Hide Audit Events (Orders/Invoices Only)</option>
                        <option value="1" <% If auditVisibility="1" Then Response.Write "selected" %>>Show PC Updates Only (NEIL, etc.)</option>
                        <option value="2" <% If auditVisibility="2" Then Response.Write "selected" %>>Show ALL Events (Show Matched as Grey)</option>
                        <option value="3" <% If auditVisibility="3" Then Response.Write "selected" %>>Show ALL Events (Hide Matched)</option>
                        <option value="4" <% If auditVisibility="4" Then Response.Write "selected" %>>Show Audit Events Only (Raw DB Triggers)</option>
                    </select>
                </div>
                <div class="col-md-4">
                    <label for="AuditSync" class="form-label fw-bold mb-1">Audit Syncing:</label>
                    <select id="AuditSync" name="AuditSync" class="form-select">
                        <option value="0" <% If auditSync="0" Then Response.Write "selected" %>>Display Only (Don't alter math)</option>
                        <option value="1" <% If auditSync="1" Then Response.Write "selected" %>>Sync Calc. Stock to Audit (Checkpoints)</option>
                    </select>
                </div>
            </form>
        </div>
    </div>

    <% If productCode <> "" Then %>
        <% If productID = 0 Then %>
            <div class="alert alert-warning" style="max-width: 1200px;">
                Product code <strong><%=Server.HTMLEncode(productCode)%></strong> was not found in the database.
            </div>
        <% ElseIf IsObject(rs) Then %>
            
            <div class="d-flex align-items-center mb-4 bg-white p-3 shadow-sm rounded border" style="max-width: 1200px;">
                <img src="/getpic.asp?code=<%=Server.URLEncode(productCode)%>" alt="Product Image" class="me-3 product-header-img" onerror="this.style.display='none'">
                <div>
                    <h3 class="mb-1 text-primary fw-bold"><%=Server.HTMLEncode(productCode)%></h3>
                    <% If productName <> "" Then %>
                        <h5 class="text-secondary mb-0"><%=Server.HTMLEncode(productName)%></h5>
                    <% Else %>
                        <h5 class="text-muted mb-0 fst-italic">No product name available</h5>
                    <% End If %>
                </div>
            </div>
            
            <div class="table-responsive bg-white shadow-sm rounded">
                <table class="table table-hover table-bordered mb-0">
                    <thead class="table-dark">
                        <tr>
                            <th>Date</th>
                            <th>Type</th>
                            <th>Reference / User</th>
                            <th>Status / PC</th>
                            <th>Sys PrevStock</th>
                            <th>Qty Change</th>
                            <th>Calc. Stock</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="table-secondary">
                            <td><em><% If startDate <> "" Then Response.Write Server.HTMLEncode(startDate) Else Response.Write "Baseline" End If %></em></td>
                            <td colspan="5"><em><%=snapshotInfo%></em></td>
                            <td class="fw-bold fs-5"><%=startingStock%></td>
                        </tr>
                        
                        <%
                        If rs.EOF Then
                            Response.Write "<tr><td colspan='7' class='text-center'>No transactions found.</td></tr>"
                        Else
                            rowCount = 0
                            Do While Not rs.EOF 
                                rowCount = rowCount + 1
                                ' FLUSH BUFFER EVERY 100 ROWS TO PREVENT IIS TIMEOUTS & MEMORY ERRORS
                                If rowCount Mod 100 = 0 Then Response.Flush()
                            
                                If IsNull(rs("TransDate")) Then transactionDate = "Not Recorded" Else transactionDate = rs("TransDate")
                                
                                transType = rs("TransType")
                                qty = 0
                                If Not IsNull(rs("Amount")) Then qty = CLng(rs("Amount"))
                                ref = rs("Ref")
                                status = rs("Status")
                                
                                If Not IsNull(rs("PrevStockSys")) Then prevStockSys = CLng(rs("PrevStockSys")) Else prevStockSys = "-"
                                If Not IsNull(rs("StockAfterSys")) Then stockAfterSys = CLng(rs("StockAfterSys")) Else stockAfterSys = "-"
                                If Not IsNull(rs("IsMatchedOrder")) Then isMatchedOrder = CInt(rs("IsMatchedOrder")) Else isMatchedOrder = 0
                                If Not IsNull(rs("IsMatchedInvoice")) Then isMatchedInvoice = CInt(rs("IsMatchedInvoice")) Else isMatchedInvoice = 0

                                isDuplicate = False
                                If transType = "ADJ" And (isMatchedOrder = 1 Or isMatchedInvoice = 1) Then isDuplicate = True

                                showRow = True
                                If isDuplicate And auditVisibility = "3" Then showRow = False

                                If qty <> 0 Then
                                    rowClass = ""
                                    syncBadge = ""

                                    If auditVisibility = "4" Then isDuplicate = False

                                    If Not isDuplicate Then
                                        If transType = "IN" Or transType = "ADJ" Then
                                            currentCalculatedStock = currentCalculatedStock + qty
                                        ElseIf transType = "OUT" Then
                                            currentCalculatedStock = currentCalculatedStock - qty
                                        End If
                                    End If

                                    If transType = "ADJ" And auditSync = "1" And stockAfterSys <> "-" Then
                                        currentCalculatedStock = stockAfterSys
                                        rowClass = "sync-row"
                                        syncBadge = " <span class='badge bg-primary ms-1' title='Calculated stock was re-synced to match this audit log'>Synced</span>"
                                    End If

                                    If transType = "OUT" Then
                                        displayQty = "-" & qty
                                    Else
                                        If qty > 0 Then displayQty = "+" & qty Else displayQty = CStr(qty)
                                    End If

                                    If isDuplicate Then
                                        cssClass = "text-muted fw-bold"
                                        rowClass = rowClass & " duplicate-row"
                                        If isMatchedOrder = 1 Then ref = ref & " (Order Match)"
                                        If isMatchedInvoice = 1 Then ref = ref & " (Invoice Match)"
                                    Else
                                        If transType = "IN" Then cssClass = "qty-in"
                                        If transType = "OUT" Then cssClass = "qty-out"
                                        If transType = "ADJ" Then 
                                            If qty > 0 Then cssClass = "qty-adj" Else cssClass = "qty-out"
                                        End If
                                    End If

                                    If Not isDuplicate And rowClass = "" And prevStockSys <> "-" Then
                                        Dim expectedStockBeforeTx : expectedStockBeforeTx = currentCalculatedStock
                                        If transType = "OUT" Then expectedStockBeforeTx = currentCalculatedStock + qty 
                                        If transType = "ADJ" And auditSync = "0" Then expectedStockBeforeTx = currentCalculatedStock - qty
                                        If expectedStockBeforeTx <> prevStockSys Then rowClass = "drift-warning" 
                                    End If
                                    
                                    If showRow Then
                        %>
                        <tr class="<%=rowClass%>">
                            <td><%=transactionDate%></td>
                            <td>
                                <% If transType = "IN" Then %>
                                    <span class="badge bg-success">IN (Purchase)</span>
                                <% ElseIf transType = "OUT" Then %>
                                    <span class="badge bg-danger">OUT (Order)</span>
                                <% ElseIf transType = "ADJ" And isDuplicate And auditVisibility <> "4" Then %>
                                    <span class="badge bg-light text-secondary border border-secondary">ADJ (Matched)</span>
                                <% ElseIf transType = "ADJ" Then %>
                                    <span class="badge border border-info text-dark">ADJ (Audit)</span>
                                <% End If %>
                            </td>
                            <td><%=ref%></td>
                            <td><span class="badge bg-secondary"><%=status%></span></td>
                            <td class="text-muted"><%=prevStockSys%></td>
                            <td class="<%=cssClass%>"><%=displayQty%></td>
                            <td class="fw-bold fs-5"><%=currentCalculatedStock%><%=syncBadge%></td>
                        </tr>
                        <% 
                                    End If 
                                End If 
                                rs.MoveNext
                            Loop 
                        End If
                        rs.Close
                        Set rs = Nothing
                        Set cmd = Nothing
                        conn.Close
                        Set conn = Nothing
                        %>
                    </tbody>
                </table>
            </div>

            <% discrepancy = currentCalculatedStock - recordedNumInStock %>
            
            <div class="card mt-4 shadow-sm" style="max-width: 500px;">
                <div class="card-header bg-dark text-white fw-bold">
                    Audit Result
                </div>
                <ul class="list-group list-group-flush">
                    <li class="list-group-item d-flex justify-content-between align-items-center">
                        Starting Stock Baseline
                        <span class="badge bg-secondary rounded-pill fs-6"><%=startingStock%></span>
                    </li>
                    <li class="list-group-item d-flex justify-content-between align-items-center">
                        <strong>Expected Stock Level</strong>
                        <span class="badge bg-primary rounded-pill fs-6"><%=currentCalculatedStock%></span>
                    </li>
                    <li class="list-group-item d-flex justify-content-between align-items-center">
                        Database `NumInStock`
                        <span class="badge bg-info rounded-pill fs-6"><%=recordedNumInStock%></span>
                    </li>
                    <li class="list-group-item d-flex justify-content-between align-items-center fw-bold">
                        Discrepancy (Expected vs Database)
                        <% If discrepancy = 0 Then %>
                            <span class="badge bg-success rounded-pill fs-6">Match (0)</span>
                        <% Else %>
                            <span class="badge bg-warning text-dark rounded-pill fs-6"><%=discrepancy%></span>
                        <% End If %>
                    </li>
                </ul>
            </div>

        <% End If %>
    <% End If %>

</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>

<script>
document.addEventListener("DOMContentLoaded", function() {
    const input = document.getElementById("ProductCode");
    const datalist = document.getElementById("productCodes");
    let timeoutId;

    input.addEventListener("input", function() {
        clearTimeout(timeoutId);
        const query = this.value;
        
        if (query.length > 1) {
            timeoutId = setTimeout(() => {
                fetch("?action=search&q=" + encodeURIComponent(query))
                    .then(response => response.json())
                    .then(data => {
                        datalist.innerHTML = "";
                        data.forEach(item => {
                            let option = document.createElement("option");
                            option.value = item.c;
                            option.text = item.n; // Sets the label in the dropdown
                            datalist.appendChild(option);
                        });
                    })
                    .catch(err => console.error("Search error:", err));
            }, 250); 
        } else {
            datalist.innerHTML = "";
        }
    });
});
</script>
</body>
</html>