Using Standalone Page with Custom Files (v2025)

I have a standalone page that works as intended. I’ve tried adding it to a custom file using an include statement. It works through most of the page. When I click the create button it fails. No errors on the web server. No updates to the database.

Code:

  1. You did not post your code.
  2. Avoid using standalone page, read How to Load Data from Database into Custom Files (v2025).

The Code

<?php
// copy_purchase_order.php
// Standalone page to copy a Purchase Order and selected materials.
// After submit, show success with new PO number and exit button.

declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

require "/var/www/ams/_amsuploads/files/custom/connection.php"; // <-- adjust path as needed

if (!isset($link) || !($link instanceof mysqli)) {
    http_response_code(500);
    exit("DB connection not found.");
}

// ------------------ Helpers ------------------
function h(?string $s): string
{
    return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

// ------------------ State ------------------

// From GET for the "normal" view
$selectedDeptId = isset($_GET['dept_id']) ? (int)$_GET['dept_id'] : 0;
$selectedPoId   = isset($_GET['source_po']) ? (int)$_GET['source_po'] : 0;

$message      = "";
$error        = "";
$newPoIdInt   = null;  // When copy succeeds
$newPoNumber  = "";    // PurchaseOrderNumber from trigger

// ------------------ Handle POST (copy PO) ------------------
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $sourcePoId     = isset($_POST['source_po_id']) ? (int)$_POST['source_po_id'] : 0;
    $selectedDeptId = isset($_POST['dept_id']) ? (int)$_POST['dept_id'] : 0;

    $selectedMaterials = isset($_POST['materials']) && is_array($_POST['materials'])
        ? array_map('intval', $_POST['materials'])
        : [];

    $qtyPosted         = isset($_POST['qty'])          && is_array($_POST['qty'])          ? $_POST['qty']          : [];
    $unitPosted        = isset($_POST['unit'])         && is_array($_POST['unit'])         ? $_POST['unit']         : [];
    $pricePosted       = isset($_POST['price'])        && is_array($_POST['price'])        ? $_POST['price']        : [];
    $discPercentPosted = isset($_POST['disc_percent']) && is_array($_POST['disc_percent']) ? $_POST['disc_percent'] : [];
    $discDollarsPosted = isset($_POST['disc_dollars']) && is_array($_POST['disc_dollars']) ? $_POST['disc_dollars'] : [];
    $notesPosted       = isset($_POST['notes'])        && is_array($_POST['notes'])        ? $_POST['notes']        : [];

    if ($sourcePoId <= 0 || empty($selectedMaterials)) {
        $error = "Please select a source Purchase Order and at least one material line.";
    } else {
        $link->begin_transaction();
        try {
            // 1) Fetch source PO
            $sqlSourcePo = "
                SELECT *
                FROM tblPurchaseOrder
                WHERE PurchaseOrderID = ?
            ";
            $stmt = $link->prepare($sqlSourcePo);
            $stmt->bind_param("i", $sourcePoId);
            $stmt->execute();
            $sourcePo = $stmt->get_result()->fetch_assoc();
            $stmt->close();

            if (!$sourcePo) {
                throw new Exception("Source Purchase Order not found.");
            }

            // 2) Insert new PO: copy fields you specified
            //    PurchaseOrderDepartment, Vendor, VendorPOC,
            //    RequisitionedBy, AuthorizedBy, Terms
            //    Set PurchaseOrderDate = today, PurchaseOrderStatus = 1
            $today  = date('Y-m-d');
            $status = 1;

            $sqlInsertPo = "
                INSERT INTO tblPurchaseOrder (
                    PurchaseOrderDepartment,
                    Vendor,
                    VendorPOC,
                    RequisitionedBy,
                    AuthorizedBy,
                    Terms,
                    PurchaseOrderDate,
                    PurchaseOrderStatus
                ) VALUES (
                    ?, ?, ?, ?, ?, ?, ?, ?
                )
            ";

            $stmt = $link->prepare($sqlInsertPo);
            $stmt->bind_param(
                "iiiiiisi",
                $sourcePo['PurchaseOrderDepartment'],
                $sourcePo['Vendor'],
                $sourcePo['VendorPOC'],
                $sourcePo['RequisitionedBy'],
                $sourcePo['AuthorizedBy'],
                $sourcePo['Terms'],
                $today,
                $status
            );
            if (!$stmt->execute()) {
                throw new Exception("Insert PO failed: " . $stmt->error);
            }
            $newPoId = $stmt->insert_id;
            $stmt->close();

            if ($newPoId <= 0) {
                throw new Exception("Failed to create new Purchase Order.");
            }

            // 3) Copy selected materials (ItemID from source, rest from POST)
            $placeholders = implode(',', array_fill(0, count($selectedMaterials), '?'));
            $typesIn      = str_repeat('i', count($selectedMaterials));

            $sqlMaterials = "
                SELECT 
                    m.*
                FROM tblPurchaseOrder_Materials m
                WHERE m.PurchaseOrderID = ?
                  AND m.PurchaseOrderMaterialsID IN ($placeholders)
            ";

            $stmt   = $link->prepare($sqlMaterials);
            $params = array_merge([$sourcePoId], $selectedMaterials);
            $typesAll = 'i' . $typesIn;

            $bindArgs = [];
            $bindArgs[] = $typesAll;
            foreach ($params as $k => $v) {
                $bindArgs[] = &$params[$k];
            }
            call_user_func_array([$stmt, 'bind_param'], $bindArgs);

            $stmt->execute();
            $resultMaterials = $stmt->get_result();

            $sqlInsertMat = "
                INSERT INTO tblPurchaseOrder_Materials (
                    PurchaseOrderID,
                    ItemID,
                    QuantityOrdered,
                    UnitOfIssue,
                    QuantityReceived,
                    QuantityBackOrdered,
                    QuantityPerUnit,
                    UnitPrice,
                    DiscountPercent,
                    DiscountDollars,
                    Notes
                ) VALUES (
                    ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
                )
            ";
            $stmtInsertMat = $link->prepare($sqlInsertMat);

            while ($row = $resultMaterials->fetch_assoc()) {
                $matId = (int)$row['PurchaseOrderMaterialsID'];

                $q = isset($qtyPosted[$matId]) && $qtyPosted[$matId] !== ''
                    ? (float)$qtyPosted[$matId] : 0.0;
                $u = isset($unitPosted[$matId]) && $unitPosted[$matId] !== ''
                    ? (int)$unitPosted[$matId] : 0;
                $p = isset($pricePosted[$matId]) && $pricePosted[$matId] !== ''
                    ? (float)$pricePosted[$matId] : 0.0;

                if ($q <= 0 || $u <= 0 || $p < 0) {
                    // Skip invalid rows
                    continue;
                }

                $discPercent = isset($discPercentPosted[$matId]) && $discPercentPosted[$matId] !== ''
                    ? (float)$discPercentPosted[$matId]
                    : (float)($row['DiscountPercent'] ?? 0.00);

                $discDollars = isset($discDollarsPosted[$matId]) && $discDollarsPosted[$matId] !== ''
                    ? (float)$discDollarsPosted[$matId]
                    : (float)($row['DiscountDollars'] ?? 0.00);

                $noteText = isset($notesPosted[$matId])
                    ? trim((string)$notesPosted[$matId])
                    : (string)($row['Notes'] ?? '');

                $QuantityPerUnit    = isset($row['QuantityPerUnit']) ? (int)$row['QuantityPerUnit'] : 1;
                $QuantityReceived    = 0.0;
                $QuantityBackOrdered = 0.0;

                $stmtInsertMat->bind_param(
                    "iidiiidddds",
                    $newPoId,
                    $row['ItemID'],
                    $q,
                    $u,
                    $QuantityReceived,
                    $QuantityBackOrdered,
                    $QuantityPerUnit,
                    $p,
                    $discPercent,
                    $discDollars,
                    $noteText
                );
                if (!$stmtInsertMat->execute()) {
                    throw new Exception("Insert PO material failed: " . $stmtInsertMat->error);
                }
            }

            $stmtInsertMat->close();
            $stmt->close();

            $link->commit();

            // Look up generated PO number (from your BEFORE trigger)
            $newPoIdInt = (int)$newPoId;

            $sqlNewPo = "
                SELECT PurchaseOrderNumber
                FROM tblPurchaseOrder
                WHERE PurchaseOrderID = ?
            ";
            $stmt = $link->prepare($sqlNewPo);
            $stmt->bind_param("i", $newPoIdInt);
            $stmt->execute();
            $rowNewPo = $stmt->get_result()->fetch_assoc();
            $stmt->close();

            if ($rowNewPo && !empty($rowNewPo['PurchaseOrderNumber'])) {
                $newPoNumber = $rowNewPo['PurchaseOrderNumber'];
            }

            $message = "New Purchase Order created successfully.";

        } catch (Throwable $ex) {
            $link->rollback();
            $error = "Error creating new Purchase Order: " . $ex->getMessage();
        }
    }
}

// ------------------ Lookups (Departments, Units, PO list, header/materials) ------------------

// Departments
$sqlDept = "
    SELECT DepartmentID, Department, DeptAbbreviation
    FROM tblDepartments
    ORDER BY Department
";
$departments = [];
if ($deptRes = $link->query($sqlDept)) {
    $departments = $deptRes->fetch_all(MYSQLI_ASSOC);
}

// Unit of Issue (for "EA, Each" style labels)
$sqlUoi = "
    SELECT UnitOfIssueID, UnitOfIssue, UnitOfIssueAbbreviation
    FROM tblUnitOfIssue
    ORDER BY UnitOfIssueAbbreviation, UnitOfIssue
";
$unitOfIssueOptions = [];
if ($uoiRes = $link->query($sqlUoi)) {
    $unitOfIssueOptions = $uoiRes->fetch_all(MYSQLI_ASSOC);
}

// PO list (filtered by Department if chosen)
$poList = null;
if ($selectedDeptId > 0) {
    $sqlPoList = "
        SELECT 
            po.PurchaseOrderID,
            po.PurchaseOrderNumber,
            DATE_FORMAT(po.PurchaseOrderDate, '%m/%d/%Y') AS PurchaseOrderDate,
            po.Vendor,
            po.PurchaseOrderDepartment,
            v.VendorName
        FROM tblPurchaseOrder po
        LEFT JOIN tblVendors v ON v.VendorID = po.Vendor
        WHERE po.PurchaseOrderDepartment = ?
        ORDER BY po.PurchaseOrderDate DESC, po.PurchaseOrderID DESC
    ";
    $stmt = $link->prepare($sqlPoList);
    $stmt->bind_param("i", $selectedDeptId);
    $stmt->execute();
    $poList = $stmt->get_result();
    $stmt->close();
} else {
    $sqlPoList = "
        SELECT 
            po.PurchaseOrderID,
            po.PurchaseOrderNumber,
            DATE_FORMAT(po.PurchaseOrderDate, '%m/%d/%Y') AS PurchaseOrderDate,
            po.Vendor,
            po.PurchaseOrderDepartment,
            v.VendorName
        FROM tblPurchaseOrder po
        LEFT JOIN tblVendors v ON v.VendorID = po.Vendor
        ORDER BY po.PurchaseOrderDate DESC, po.PurchaseOrderID DESC
    ";
    $poList = $link->query($sqlPoList);
}

// If we are in success view, we don't need header/materials
$poHeader  = null;
$materials = [];

if ($newPoIdInt === null && $selectedPoId > 0) {
    // Header query (simplified from your print page)
    $sqlHeader = "
        SELECT
            po.PurchaseOrderID,
            po.PurchaseOrderNumber,
            DATE_FORMAT(po.PurchaseOrderDate, '%m/%d/%Y') AS PurchaseOrderDate,
            po.SalesOrderNumber,
            ROUND(po.PurchaseOrderTotal, 2) AS PurchaseOrderTotal,
            po.EstimatedShipDate,
            po.FOBPoint,
            po.Notes,
            d.Department,
            v.VendorName,
            v.VendorAddress,
            v.VendorPhone,
            w.WorkOrderID,
            IFNULL(CONCAT('WO# ', w.WorkOrderNumber), '') AS WorkOrderNumber,
            req.FullName AS Technician,
            auth.FullName AS AuthorizedBy,
            ship.ShippingMethod,
            terms.Terms,
            a.AssetFullName AS AssetFullName
        FROM tblPurchaseOrder po
        LEFT JOIN tblWorkOrder w ON w.WorkOrderID = po.WorkOrderID
        LEFT JOIN tblDepartments d ON po.PurchaseOrderDepartment = d.DepartmentID
        LEFT JOIN accounts req ON po.RequisitionedBy = req.AccountID
        LEFT JOIN tblPurchaseOrder_LU_ShippingMethods ship ON po.ShippingMethod = ship.ShippingMethodID
        LEFT JOIN tblPurchaseOrder_LU_Terms terms ON po.Terms = terms.AccountTermsID
        LEFT JOIN accounts auth ON po.AuthorizedBy = auth.AccountID
        LEFT JOIN tblAssets a ON a.AssetID = po.AssetID
        LEFT JOIN tblVendors v ON v.VendorID = po.Vendor
        WHERE po.PurchaseOrderID = ?
    ";
    $stmtH = $link->prepare($sqlHeader);
    $stmtH->bind_param("i", $selectedPoId);
    $stmtH->execute();
    $poHeader = $stmtH->get_result()->fetch_assoc();
    $stmtH->close();

    // Materials for selected PO
    $sqlMat = "
        SELECT
            m.PurchaseOrderMaterialsID,
            m.ItemID,
            m.QuantityOrdered,
            m.UnitOfIssue,
            m.QuantityReceived,
            m.QuantityBackOrdered,
            m.QuantityPerUnit,
            m.UnitPrice,
            m.DiscountPercent,
            m.DiscountDollars,
            m.Notes,
            i.ItemDescription
        FROM tblPurchaseOrder_Materials m
        LEFT JOIN tblItems i ON i.ItemID = m.ItemID
        WHERE m.PurchaseOrderID = ?
        ORDER BY m.PurchaseOrderMaterialsID
    ";
    $stmtM = $link->prepare($sqlMat);
    $stmtM->bind_param("i", $selectedPoId);
    $stmtM->execute();
    $materials = $stmtM->get_result()->fetch_all(MYSQLI_ASSOC);
    $stmtM->close();
}
?>

    <style>

        .message {
            padding: 0.5rem 1rem;
            margin-bottom: 1rem;
            border-radius: 4px;
        }
        .message.success {
            background: #e6ffed;
            border: 1px solid #b7f5c2;
        }
        .message.error {
            background: #ffecec;
            border: 1px solid #f5b7b7;
        }
        label {
            font-weight: bold;
            font-size: 1.2em;
        }
        select {
            min-width: 250px;
            font-size: 1.1em;
        }
        .form-row {
            margin-bottom: 0.75rem;
        }
        .po-header {
            border: 1px solid #ccc;
            padding: 0.75rem;
            margin-top: 1rem;
            margin-bottom: 1rem;
            border-radius: 4px;
            background: #f9f9f9;
            font-size: 0.9rem;
        }
        .po-header h2 {
            margin-top: 0;
            margin-bottom: 0.5rem;
            font-size: 1.1rem;
        }
        .po-header table {
            width: 100%;
            border-collapse: collapse;
        }
        .po-header td {
            padding: 2px 4px;
            vertical-align: top;
        }
        table.materials {
            border-collapse: collapse;
            width: 100%;
            margin-top: 1rem;
        }
        table.materials th, table.materials td {
            border: 1px solid #ccc;
            padding: 0.35rem 0.5rem;
            font-size: 0.95rem;
        }
        table.materials th {
            background: #f2f2f2;
        }
        table.materials tbody tr:nth-child(even) td {
            background: #f9f9f9;
        }
        input[type="number"] {
            width: 80px;
        }
        textarea {
            width: 100%;
            height: 40px;
            font-size: 0.85rem;
        }
        .btn {
            display: inline-block;
            padding: 0.4rem 0.8rem;
            font-size: 0.9rem;
            border-radius: 4px;
            border: 1px solid #999;
            background-color: #e9ecef;
            cursor: pointer;
            text-decoration: none;
            color: #000;
        }
    </style>
    <script>
        function toggleSelectAll(source) {
            const checkboxes = document.querySelectorAll('input[name="materials[]"]');
            checkboxes.forEach(cb => cb.checked = source.checked);
        }
    </script>
</head>
<body>
<h1>Copy Purchase Order</h1>

<?php if ($message): ?>
    <div class="message success"><?php echo h($message); ?></div>
<?php endif; ?>

<?php if ($error): ?>
    <div class="message error"><?php echo h($error); ?></div>
<?php endif; ?>

<?php if ($newPoIdInt !== null): ?>
    <!-- SUCCESS VIEW -->
    <div class="po-header">
        <h2>New Purchase Order Created</h2>
        <p>
            New Purchase Order ID:
            <strong><?php echo (int)$newPoIdInt; ?></strong><br>
            <?php if ($newPoNumber !== ""): ?>
                New Purchase Order Number:
                <strong><?php echo h($newPoNumber); ?></strong>
            <?php endif; ?>
        </p>
        <p>
            <a class="btn btn-primary"
               href="/TblPurchaseOrderView/<?php echo (int)$newPoIdInt; ?>?showdetail=">
               Open Purchase Order
            </a>
            &nbsp;
            <!-- Change href below to wherever you want them to go when done -->
            <a class="btn btn-secondary" href="/TblPurchaseOrderList">
                Exit
            </a>
        </p>
    </div>

<?php else: ?>
    <!-- NORMAL UI (filter + header + materials) -->

    <!-- Department + PO filter -->
    <form id="filterForm" method="get" action="">
        <div class="form-row">
            <label for="dept_id">Department:</label><br>
            <select name="dept_id" id="dept_id" onchange="this.form.submit()">
                <option value="">-- All Departments --</option>
                <?php foreach ($departments as $dept): ?>
                    <option value="<?php echo (int)$dept['DepartmentID']; ?>"
                        <?php if ($selectedDeptId === (int)$dept['DepartmentID']) echo 'selected'; ?>>
                        <?php
                        $dName = $dept['Department'];
                        if (!empty($dept['DeptAbbreviation'])) {
                            $dName .= " (" . $dept['DeptAbbreviation'] . ")";
                        }
                        echo h($dName);
                        ?>
                    </option>
                <?php endforeach; ?>
            </select>
        </div>

        <div class="form-row">
            <label for="source_po">Select Purchase Order to copy:</label><br>
            <select name="source_po" id="source_po" onchange="this.form.submit()">
                <option value="">-- Choose a Purchase Order --</option>
                <?php if ($poList && $poList->num_rows > 0): ?>
                    <?php while ($row = $poList->fetch_assoc()): ?>
                        <?php
                        $display = trim((string)$row['PurchaseOrderNumber']);
                        if (!empty($row['VendorName'])) {
                            $display .= " - " . $row['VendorName'];
                        }
                        if (!empty($row['PurchaseOrderDate'])) {
                            $display .= " (" . $row['PurchaseOrderDate'] . ")";
                        }
                        ?>
                        <option value="<?php echo (int)$row['PurchaseOrderID']; ?>"
                            <?php if ($selectedPoId === (int)$row['PurchaseOrderID']) echo 'selected'; ?>>
                            <?php echo h($display); ?>
                        </option>
                    <?php endwhile; ?>
                <?php endif; ?>
            </select>
        </div>
    </form>

    <?php if ($selectedPoId > 0 && $poHeader): ?>
        <!-- PO Header -->
        <div class="po-header">
            <h2>
                PO #<?php echo h((string)$poHeader['PurchaseOrderNumber']); ?>
                <?php if (!empty($poHeader['PurchaseOrderDate'])): ?>
                    &mdash; <?php echo h((string)$poHeader['PurchaseOrderDate']); ?>
                <?php endif; ?>
            </h2>
            <table>
                <tr>
                    <td style="width:50%;">
                        <strong>Vendor:</strong> <?php echo h((string)$poHeader['VendorName']); ?><br>
                        <?php if (!empty($poHeader['VendorAddress'])): ?>
                            <?php echo nl2br(h((string)$poHeader['VendorAddress'])); ?><br>
                        <?php endif; ?>
                        <?php if (!empty($poHeader['VendorPhone'])): ?>
                            Phone: <?php echo h((string)$poHeader['VendorPhone']); ?><br>
                        <?php endif; ?>
                    </td>
                    <td style="width:50%;">
                        <?php if (!empty($poHeader['Department'])): ?>
                            <strong>Department:</strong> <?php echo h((string)$poHeader['Department']); ?><br>
                        <?php endif; ?>
                        <?php if (!empty($poHeader['WorkOrderNumber'])): ?>
                            <strong>Work Order:</strong> <?php echo h((string)$poHeader['WorkOrderNumber']); ?><br>
                        <?php endif; ?>
                        <?php if (!empty($poHeader['SalesOrderNumber'])): ?>
                            <strong>SO#:</strong> <?php echo h((string)$poHeader['SalesOrderNumber']); ?><br>
                        <?php endif; ?>
                    </td>
                </tr>
                <tr>
                    <td>
                        <?php if (!empty($poHeader['AssetFullName'])): ?>
                            <strong>Asset:</strong> <?php echo h((string)$poHeader['AssetFullName']); ?><br>
                        <?php endif; ?>
                    </td>
                    <td>
                        <?php if (!empty($poHeader['Technician'])): ?>
                            <strong>Requisitioned By:</strong> <?php echo h((string)$poHeader['Technician']); ?><br>
                        <?php endif; ?>
                        <?php if (!empty($poHeader['AuthorizedBy'])): ?>
                            <strong>Authorized By:</strong> <?php echo h((string)$poHeader['AuthorizedBy']); ?><br>
                        <?php endif; ?>
                    </td>
                </tr>
                <tr>
                    <td>
                        <?php if (!empty($poHeader['EstimatedShipDate'])): ?>
                            <strong>When Ship:</strong> <?php echo h((string)$poHeader['EstimatedShipDate']); ?><br>
                        <?php endif; ?>
                        <?php if (!empty($poHeader['ShippingMethod'])): ?>
                            <strong>Ship Via:</strong> <?php echo h((string)$poHeader['ShippingMethod']); ?><br>
                        <?php endif; ?>
                    </td>
                    <td>
                        <?php if (!empty($poHeader['FOBPoint'])): ?>
                            <strong>F.O.B. Point:</strong> <?php echo h((string)$poHeader['FOBPoint']); ?><br>
                        <?php endif; ?>
                        <?php if (!empty($poHeader['Terms'])): ?>
                            <strong>Terms:</strong> <?php echo h((string)$poHeader['Terms']); ?><br>
                        <?php endif; ?>
                        <?php if (!empty($poHeader['PurchaseOrderTotal'])): ?>
                            <strong>Total:</strong> $<?php echo h((string)$poHeader['PurchaseOrderTotal']); ?><br>
                        <?php endif; ?>
                    </td>
                </tr>
                <?php if (!empty($poHeader['Notes'])): ?>
                <tr>
                    <td colspan="2">
                        <strong>Notes:</strong><br>
                        <?php echo nl2br(h((string)$poHeader['Notes'])); ?>
                    </td>
                </tr>
                <?php endif; ?>
            </table>
        </div>
    <?php endif; ?>

    <?php if ($selectedPoId > 0): ?>
        <h2>Materials for PO #<?php echo h((string)$poHeader['PurchaseOrderNumber']); ?></h2>

        <?php if (empty($materials)): ?>
            <p>No materials found for this Purchase Order.</p>
        <?php else: ?>
            <form method="post" action="">
                <input type="hidden" name="source_po_id" value="<?php echo (int)$selectedPoId; ?>">
                <input type="hidden" name="dept_id" value="<?php echo (int)$selectedDeptId; ?>">

                <table class="materials">
                    <thead>
                        <tr>
                            <th><input type="checkbox" onclick="toggleSelectAll(this)"></th>
                            <th>ItemID</th>
                            <th>Item Description</th>
                            <th>Qty Ordered</th>
                            <th>Unit Of Issue</th>
                            <th>Unit Price</th>
                            <th>Disc %</th>
                            <th>Disc $</th>
                            <th>Notes</th>
                        </tr>
                    </thead>
                    <tbody>
                    <?php foreach ($materials as $mat): ?>
                        <?php $matId = (int)$mat['PurchaseOrderMaterialsID']; ?>
                        <tr>
                            <td>
                                <input type="checkbox"
                                       name="materials[]"
                                       value="<?php echo $matId; ?>"
                                       checked>
                            </td>
                            <td><?php echo h((string)$mat['ItemID']); ?></td>
                            <td><?php echo h((string)$mat['ItemDescription']); ?></td>
                            <td>
                                <input type="number"
                                       name="qty[<?php echo $matId; ?>]"
                                       value="<?php echo h((string)$mat['QuantityOrdered']); ?>"
                                       step="0.0001"
                                       min="0">
                            </td>
                            <td>
                                <select name="unit[<?php echo $matId; ?>]">
                                    <option value="">-- select --</option>
                                    <?php foreach ($unitOfIssueOptions as $u): ?>
                                        <?php
                                        $uId    = (int)$u['UnitOfIssueID'];
                                        $abbr   = trim((string)$u['UnitOfIssueAbbreviation']);
                                        $uName  = trim((string)$u['UnitOfIssue']);
                                        if ($abbr !== '' && $uName !== '') {
                                            $label = $abbr . ", " . $uName;  // EA, Each
                                        } elseif ($abbr !== '') {
                                            $label = $abbr;
                                        } else {
                                            $label = $uName;
                                        }
                                        $sel = ($mat['UnitOfIssue'] == $uId) ? 'selected' : '';
                                        ?>
                                        <option value="<?php echo $uId; ?>" <?php echo $sel; ?>>
                                            <?php echo h($label); ?>
                                        </option>
                                    <?php endforeach; ?>
                                </select>
                            </td>
                            <td>
                                <input type="number"
                                       name="price[<?php echo $matId; ?>]"
                                       value="<?php echo h((string)$mat['UnitPrice']); ?>"
                                       step="0.0001"
                                       min="0">
                            </td>
                            <td>
                                <input type="number"
                                       name="disc_percent[<?php echo $matId; ?>]"
                                       value="<?php echo h((string)$mat['DiscountPercent']); ?>"
                                       step="0.01">
                            </td>
                            <td>
                                <input type="number"
                                       name="disc_dollars[<?php echo $matId; ?>]"
                                       value="<?php echo h((string)$mat['DiscountDollars']); ?>"
                                       step="0.01">
                            </td>
                            <td>
                                <textarea name="notes[<?php echo $matId; ?>]"><?php
                                    echo h((string)$mat['Notes']);
                                ?></textarea>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>

                <p style="margin-top: 1rem;">
                    <button type="submit" class="btn btn-primary">
                        Create New Purchase Order from Selected Lines
                    </button>
                    &nbsp;
                    <a href="/TblPurchaseOrderList">
                        Cancel
                    </a>
                </p>
            </form>
        <?php endif; ?>
    <?php endif; ?>

<?php endif; ?>

As a stand alone file not included in any way in the PHPMaker v2025 project the page works flawlessly. Once I include it in a custom file it fails upon submission. The two filters work and the resulting child recordset displays. After that it just stops when the the create new record is clicked.

Your code contains some <script> and <style> tags and style attributes, if you have enabled CSP for the project, they are not allowed by default. You should add nonce attribute to the tags, see example.

Also search this forum about how to modify the CSP directives.

For the the form submission issue, you should debug by:

  1. Enable Debug,
  2. Press F12, submit your form again, in the Console panel, check if there is any JavaScript errors,
  3. In the Network panel, select the request and check HTTP request and response, check the Payload panel to see if post data is correct, and check the HTTP response if there is any server side errors.
  4. Check the log file for errors and stack trace.

On the other hand, your code uses another connection script, it is better to use Include common files (so that you can reuse PHPMaker code and get rid of your connection.php) and convert your code to use DBAL for better long-term maintainability.

If you do not want to refactor everything at once, you can at least switch to using the DBAL connection and then obtain the native connection from it, allowing you to continue reusing your existing code while moving toward a more consistent architecture.

For example:

// Get DBAL connection (Doctrine\DBAL\Connection)
$conn = Conn(); // Assume you use the main connection

// Get native mysqli connection from DBAL
$link = $conn->getNativeConnection();

// your existing code...