<?php
include("../../../include/startup.php");
header('Content-Type: application/json');
error_reporting(E_ALL);
ini_set('display_errors', 0);

$response = ['success' => false, 'data' => [], 'message' => '', 'pagination' => []];
$action   = $_REQUEST['action'] ?? '';

// ════════════════════════════════════════════════════════════════════════════
// ACTION: allocate_stock  (unchanged)
// ════════════════════════════════════════════════════════════════════════════
if ($action === 'allocate_stock') {

    $planning_id  = intval($_POST['planning_id']  ?? 0);
    $qty_to_alloc = floatval($_POST['qty_to_alloc'] ?? 0);
    $created_by   = $_SESSION['user_id'] ?? 0;
    $now          = date('Y-m-d H:i:s');

    if ($planning_id <= 0 || $qty_to_alloc <= 0) {
        $response['message'] = 'Invalid planning ID or quantity.';
        echo json_encode($response); exit;
    }

    $anchor_res = mysqli_query($conn,
        "SELECT pp.id, pp.part_id, pp.req_qty, COALESCE(pp.allocated_qty,0) AS allocated_qty,
                pp.req_date, pp.is_shipped,
                inv.quantity_in_stock, inv.id AS inv_id
         FROM   production_planning pp
         LEFT JOIN inventory inv ON inv.item_id = pp.part_id
         WHERE  pp.id = $planning_id
           AND  pp.is_shipped IN (0, 2)
         LIMIT 1"
    );

    if (!$anchor_res || mysqli_num_rows($anchor_res) === 0) {
        $response['message'] = 'Order not found or already fully shipped.';
        echo json_encode($response); exit;
    }

    $anchor          = mysqli_fetch_assoc($anchor_res);
    $part_id         = intval($anchor['part_id']);
    $stock_available = floatval($anchor['quantity_in_stock']);

    if ($qty_to_alloc > $stock_available) {
        $response['message'] = "Cannot allocate $qty_to_alloc — only $stock_available in stock.";
        echo json_encode($response); exit;
    }

    $siblings_res = mysqli_query($conn,
        "SELECT id, req_qty, COALESCE(allocated_qty,0) AS allocated_qty, req_date, RefSalesCode
         FROM   production_planning
         WHERE  part_id    = $part_id
           AND  is_shipped IN (0, 2)
           AND  req_qty    > 0
         ORDER BY req_date ASC, id ASC"
    );

    if (!$siblings_res) {
        $response['message'] = 'Failed to fetch demand lines: ' . mysqli_error($conn);
        echo json_encode($response); exit;
    }

    $siblings = [];
    while ($r = mysqli_fetch_assoc($siblings_res)) $siblings[] = $r;

    $budget      = $qty_to_alloc;
    $allocations = [];

    foreach ($siblings as $line) {
        if ($budget <= 0) break;
        $remaining_need = floatval($line['req_qty']) - floatval($line['allocated_qty']);
        if ($remaining_need <= 0) continue;
        $give   = min($budget, $remaining_need);
        $budget -= $give;
        $allocations[] = [
            'id'            => intval($line['id']),
            'give'          => $give,
            'req_qty'       => floatval($line['req_qty']),
            'old_allocated' => floatval($line['allocated_qty']),
            'new_allocated' => floatval($line['allocated_qty']) + $give,
        ];
    }

    if (empty($allocations)) {
        $response['message'] = 'No open demand lines to allocate to.';
        echo json_encode($response); exit;
    }

    mysqli_begin_transaction($conn);
    try {
        $total_given = 0;
        foreach ($allocations as $a) {
            $new_alloc = $a['new_allocated'];
            if (!mysqli_query($conn,
                "UPDATE production_planning
                 SET    allocated_qty = $new_alloc,
                        updated_on   = '$now'
                 WHERE  id = {$a['id']}"
            )) throw new Exception('Line update failed: ' . mysqli_error($conn));
            $total_given += $a['give'];
        }

        if (!mysqli_query($conn,
            "UPDATE inventory
             SET    quantity_in_stock = quantity_in_stock - $total_given
             WHERE  item_id = $part_id"
        )) throw new Exception('Inventory update failed: ' . mysqli_error($conn));

        mysqli_commit($conn);
        $lines_touched = count($allocations);
        $response['success']         = true;
        $response['message']         = "$total_given unit(s) allocated across $lines_touched demand line(s).";
        $response['allocations']     = $allocations;
        $response['total_allocated'] = $total_given;

    } catch (Exception $e) {
        mysqli_rollback($conn);
        $response['message'] = $e->getMessage();
    }

    echo json_encode($response); exit;
}

// ════════════════════════════════════════════════════════════════════════════
// ACTION: edit_allocation  (NEW)
// Adjusts allocated_qty on a single planning line and reconciles inventory.
// The difference between old and new allocation is returned to / taken from stock.
// ════════════════════════════════════════════════════════════════════════════
if ($action === 'edit_allocation') {

    $planning_id  = intval($_POST['planning_id']  ?? 0);
    $new_alloc    = floatval($_POST['new_alloc_qty'] ?? -1);
    $now          = date('Y-m-d H:i:s');

    if ($planning_id <= 0 || $new_alloc < 0) {
        $response['message'] = 'Invalid planning ID or quantity.';
        echo json_encode($response); exit;
    }

    // Fetch the current line
    $line_res = mysqli_query($conn,
        "SELECT pp.id, pp.part_id, pp.req_qty,
                COALESCE(pp.allocated_qty, 0) AS allocated_qty,
                pp.is_shipped,
                inv.quantity_in_stock
         FROM   production_planning pp
         LEFT JOIN inventory inv ON inv.item_id = pp.part_id
         WHERE  pp.id = $planning_id
           AND  pp.is_shipped IN (0, 2)
         LIMIT 1"
    );

    if (!$line_res || mysqli_num_rows($line_res) === 0) {
        $response['message'] = 'Line not found or already shipped — cannot edit.';
        echo json_encode($response); exit;
    }

    $line            = mysqli_fetch_assoc($line_res);
    $part_id         = intval($line['part_id']);
    $old_alloc       = floatval($line['allocated_qty']);
    $req_qty         = floatval($line['req_qty']);
    $stock_available = floatval($line['quantity_in_stock']);

    // Maximum the new allocation can be = current allocation + what is in stock
    $max_alloc = $old_alloc + $stock_available;

    if ($new_alloc > $max_alloc) {
        $response['message'] = "Cannot allocate $new_alloc — only $max_alloc available (current alloc $old_alloc + stock $stock_available).";
        echo json_encode($response); exit;
    }

    // Stock delta: positive means we're RETURNING stock, negative means taking more
    $stock_delta = $old_alloc - $new_alloc; // e.g. old=10, new=6 → delta=+4 returned to stock

    mysqli_begin_transaction($conn);
    try {
        // Update planning line
        if (!mysqli_query($conn,
            "UPDATE production_planning
             SET    allocated_qty = $new_alloc,
                    updated_on   = '$now'
             WHERE  id = $planning_id"
        )) throw new Exception('Planning update failed: ' . mysqli_error($conn));

        // Reconcile inventory (add back if reducing allocation, subtract if increasing)
        if ($stock_delta != 0) {
            if (!mysqli_query($conn,
                "UPDATE inventory
                 SET    quantity_in_stock = quantity_in_stock + ($stock_delta)
                 WHERE  item_id = $part_id"
            )) throw new Exception('Inventory reconciliation failed: ' . mysqli_error($conn));
        }

        mysqli_commit($conn);

        $direction = $new_alloc < $old_alloc
            ? 'reduced by ' . ($old_alloc - $new_alloc) . ' (stock restored)'
            : ($new_alloc > $old_alloc
                ? 'increased by ' . ($new_alloc - $old_alloc)
                : 'unchanged');

        $response['success']       = true;
        $response['message']       = "Allocation $direction. New allocation: $new_alloc unit(s).";
        $response['old_alloc']     = $old_alloc;
        $response['new_alloc']     = $new_alloc;
        $response['stock_delta']   = $stock_delta;

    } catch (Exception $e) {
        mysqli_rollback($conn);
        $response['message'] = $e->getMessage();
    }

    echo json_encode($response); exit;
}

// ════════════════════════════════════════════════════════════════════════════
// ACTION: create_delivery_note  (unchanged)
// ════════════════════════════════════════════════════════════════════════════
if ($action === 'create_delivery_note') {

    $raw_ids      = $_POST['planning_ids'] ?? [];
    $planning_ids = array_map('intval', (array) $raw_ids);
    $planning_ids = array_filter($planning_ids, function($id){ return $id > 0; });
    $planning_ids = array_values($planning_ids);

    $customer_id = intval($_POST['customer_id'] ?? 0);
    $ship_id     = intval($_POST['ship_id']      ?? 1);
    $created_by  = $_SESSION['user_id'] ?? 0;
    $now         = date('Y-m-d H:i:s');
    $today       = date('Y-m-d');

    if (empty($planning_ids)) {
        $response['message'] = 'No planning lines selected.';
        echo json_encode($response); exit;
    }

    // ── Resolve customer_id if not passed ──
    if ($customer_id <= 0) {
        $first_id = $planning_ids[0];
        $cust_res = mysqli_query($conn, "SELECT customer_reff FROM production_planning WHERE id = $first_id LIMIT 1");
        if ($cust_res && $row = mysqli_fetch_assoc($cust_res)) {
            $customer_id = intval($row['customer_reff']);
        }
    }

    if ($customer_id <= 0) {
        $response['message'] = 'Could not determine customer ID.';
        echo json_encode($response); exit;
    }

    // ── Fetch allocated planning lines ──
    $ids_in    = implode(',', $planning_ids);
    $lines_res = mysqli_query($conn,
        "SELECT pp.id, pp.part_id, pp.req_qty,
                COALESCE(pp.allocated_qty, 0) AS allocated_qty,
                pp.req_date, pp.RefSalesCode, pp.customer_reff,
                pp.item_price,
                im.part_number, im.product_description,
                im.standard_cost_ebq
         FROM   production_planning pp
         LEFT JOIN item_management im ON im.id = pp.part_id
         WHERE  pp.id         IN ($ids_in)
           AND  pp.is_shipped IN (0, 2)
           AND  COALESCE(pp.allocated_qty, 0) > 0
         ORDER BY im.part_number ASC, pp.req_date ASC, pp.id ASC"
    );

    if (!$lines_res || mysqli_num_rows($lines_res) === 0) {
        $response['message'] = 'No allocated stock found for the selected lines. Allocate stock first.';
        echo json_encode($response); exit;
    }

    $lines = [];
    while ($r = mysqli_fetch_assoc($lines_res)) $lines[] = $r;

    mysqli_begin_transaction($conn);
    try {

        // ── 1. Generate delivery note number ──
        $nn_res = mysqli_query($conn,
            "SELECT CASE
                WHEN MAX(note_number) < 60000 OR MAX(note_number) IS NULL
                THEN 60000
                ELSE MAX(note_number) + 1
             END AS new_note_number
             FROM delivery_notes"
        );
        if (!$nn_res) throw new Exception('Failed to generate note number: ' . mysqli_error($conn));
        $note_number = (int) mysqli_fetch_assoc($nn_res)['new_note_number'];

        // ── 2. Insert delivery note header ──
        if (!mysqli_query($conn,
            "INSERT INTO delivery_notes SET
             note_number   = '$note_number',
             delivery_date = '$today',
             customer_id   = '$customer_id',
             ship_id       = '$ship_id',
             delivery_note = '',
             created_by    = '$created_by',
             created_on    = '$now',
             updated_by    = '$created_by',
             updated_on    = '$now'"
        )) throw new Exception('delivery_notes insert failed: ' . mysqli_error($conn));

        $delivery_note_id = mysqli_insert_id($conn);

        // ── 3. Generate sales invoice number ──
        $inv_nn_res = mysqli_query($conn,
            "SELECT IFNULL(MAX(invoice_number), 0) + 1 AS new_invoice_number FROM sales_invoices"
        );
        if (!$inv_nn_res) throw new Exception('Failed to generate invoice number: ' . mysqli_error($conn));
        $raw_inv_num    = (int) mysqli_fetch_assoc($inv_nn_res)['new_invoice_number'];
        $invoice_number = str_pad($raw_inv_num, 4, '1000', STR_PAD_LEFT);

        // ── 4. Pull customer addresses ──
        $cust_addr_res = mysqli_query($conn,
            "SELECT
                 dam.id                 AS delivery_add_id,
                 dam.delivery_address_1, dam.delivery_address_2,
                 dam.delivery_address_3, dam.delivery_add_postcode,
                 cm.invoice_address_1, cm.invoice_address_2,
                 cm.invoice_address_3, cm.invoice_add_postcode
             FROM client_management cm
             LEFT JOIN client_delivery_address_mapping dam
                    ON dam.customer_id = cm.id
             WHERE cm.id = $customer_id
             ORDER BY dam.id ASC
             LIMIT 1"
        );
        if (!$cust_addr_res) throw new Exception('Failed to fetch customer address: ' . mysqli_error($conn));

        $cust_addr = mysqli_num_rows($cust_addr_res) ? mysqli_fetch_assoc($cust_addr_res) : [];

        $del_addr_1   = $conn->real_escape_string($cust_addr['delivery_address_1'] ?? '');
        $del_addr_2   = $conn->real_escape_string($cust_addr['delivery_address_2'] ?? '');
        $del_addr_3   = $conn->real_escape_string($cust_addr['delivery_address_3'] ?? '');
        $del_postcode = $conn->real_escape_string($cust_addr['delivery_add_postcode'] ?? '');
        $del_add_id   = intval($cust_addr['delivery_add_id'] ?? 0);
        $inv_addr_1   = $conn->real_escape_string($cust_addr['invoice_address_1'] ?? '');
        $inv_addr_2   = $conn->real_escape_string($cust_addr['invoice_address_2'] ?? '');
        $inv_addr_3   = $conn->real_escape_string($cust_addr['invoice_address_3'] ?? '');
        $inv_postcode = $conn->real_escape_string($cust_addr['invoice_add_postcode'] ?? '');

        $order_number_ref = $conn->real_escape_string($lines[0]['RefSalesCode'] ?? '');

        // ── 5. Insert sales invoice header ──
        if (!mysqli_query($conn,
            "INSERT INTO sales_invoices SET
             invoice_number        = '$invoice_number',
             invoice_date          = '$today',
             delivery_date         = '$today',
             delivery_note_no      = '$delivery_note_id',
             order_number          = '$order_number_ref',
             customer_id           = '$customer_id',
             ship_id               = '$ship_id',
             vendor_id             = '',
             delivery_address_1    = '$del_addr_1',
             delivery_address_2    = '$del_addr_2',
             delivery_address_3    = '$del_addr_3',
             delivery_add_postcode = '$del_postcode',
             delivery_add_id       = '$del_add_id',
             invoice_address_1     = '$inv_addr_1',
             invoice_address_2     = '$inv_addr_2',
             invoice_address_3     = '$inv_addr_3',
             invoice_add_postcode  = '$inv_postcode',
             created_by            = '$created_by',
             created_on            = '$now',
             updated_by            = '$created_by'"
        )) throw new Exception('sales_invoices insert failed: ' . mysqli_error($conn));

        $sales_invoice_id = mysqli_insert_id($conn);

        // ── 6. Process each planning line ──
        $mapping_count     = 0;
        $total_shipped     = 0;
        $fully_shipped     = 0;
        $partially_shipped = 0;
        $ordering          = 1;

        foreach ($lines as $line) {
            $qty_this_line = floatval($line['allocated_qty']);
            $req_qty       = floatval($line['req_qty']);
            $plan_id       = intval($line['id']);
            $part_id_line  = intval($line['part_id']);

            $unit_price = floatval($line['item_price'] ?? 0);
            if ($unit_price == 0) $unit_price = floatval($line['standard_cost_ebq'] ?? 0);

            $line_total = round($qty_this_line * $unit_price, 2);
            $desc       = $conn->real_escape_string($line['product_description'] ?? '');
            $part_num   = $conn->real_escape_string($line['part_number'] ?? '');
            $ref_code   = $conn->real_escape_string($line['RefSalesCode'] ?? '');

            // ── 6a. Delivery note mapping line ──
            if (!mysqli_query($conn,
                "INSERT INTO delivery_note_mapping SET
                 delivery_note_id = '$delivery_note_id',
                 quantity         = '$qty_this_line',
                 order_number     = '$plan_id',
                 part_number      = '$part_id_line',
                 description      = '$desc',
                 created_by       = '$created_by',
                 created_on       = '$now',
                 updated_by       = '$created_by'"
            )) throw new Exception("delivery_note_mapping insert failed (line $plan_id): " . mysqli_error($conn));

            $mapping_count++;
            $total_shipped += $qty_this_line;

            // ── 6b. Update production_planning ──
            if ($qty_this_line >= $req_qty) {
                if (!mysqli_query($conn,
                    "UPDATE production_planning SET
                     shipped_qty   = shipped_qty + $qty_this_line,
                     allocated_qty = 0,
                     req_qty       = 0,
                     is_shipped    = 1,
                     updated_on    = '$now'
                     WHERE id = $plan_id"
                )) throw new Exception("pp full-ship update failed (line $plan_id): " . mysqli_error($conn));
                $fully_shipped++;
            } else {
                if (!mysqli_query($conn,
                    "UPDATE production_planning SET
                     shipped_qty   = shipped_qty + $qty_this_line,
                     allocated_qty = 0,
                     req_qty       = req_qty - $qty_this_line,
                     is_shipped    = 2,
                     updated_on    = '$now'
                     WHERE id = $plan_id"
                )) throw new Exception("pp partial-ship update failed (line $plan_id): " . mysqli_error($conn));
                $partially_shipped++;
            }

            // ── 6c. Sales invoice mapping line ──
            if (!mysqli_query($conn,
                "INSERT INTO sales_invoice_mapping SET
                 sales_id         = '$sales_invoice_id',
                 ordering         = '$ordering',
                 part_number      = '$part_id_line',
                 order_number_mpp = '$plan_id',
                 description      = '$desc',
                 issue            = '',
                 quantity         = '$qty_this_line',
                 unit_price       = '$unit_price',
                 total            = '$line_total',
                 created_by       = '$created_by',
                 created_on       = '$now',
                 updated_by       = '$created_by'"
            )) throw new Exception("sales_invoice_mapping insert failed (line $plan_id): " . mysqli_error($conn));

            $ordering++;
        }

        // ── 7. Commit ──
        mysqli_commit($conn);

        $response['success']          = true;
        $response['message']          = "Delivery Note #$note_number and Sales Invoice #$invoice_number created "
                                      . "with $mapping_count line(s). "
                                      . "$total_shipped unit(s) shipped "
                                      . "($fully_shipped fully shipped, $partially_shipped partial).";
        $response['note_number']      = $note_number;
        $response['invoice_number']   = $invoice_number;
        $response['sales_invoice_id'] = $sales_invoice_id;
        $response['delivery_note_id'] = $delivery_note_id;
        $response['mapping_rows']     = $mapping_count;
        $response['total_shipped']    = $total_shipped;

    } catch (Exception $e) {
        mysqli_rollback($conn);
        $response['message'] = $e->getMessage();
    }

    echo json_encode($response); exit;
}

// ════════════════════════════════════════════════════════════════════════════
// ACTION: get_ready_orders  (unchanged)
// ════════════════════════════════════════════════════════════════════════════
if ($action === 'get_ready_orders') {

    $page     = max(1, intval($_GET['current_page'] ?? 1));
    $per_page = max(1, intval($_GET['per_page'] ?? 25));
    $offset   = ($page - 1) * $per_page;

    $ref_search    = trim($_GET['ref']           ?? '');
    $code_search   = trim($_GET['code']          ?? '');
    $part_search   = trim($_GET['part']          ?? '');
    $date_from     = trim($_GET['date_from']     ?? '');
    $date_to       = trim($_GET['date_to']       ?? '');
    $status_filter = trim($_GET['status_filter'] ?? '');

    $where = [
        "im.usual_source = 'Manufactured'",
        "pp.req_qty > 0",
        "pp.is_shipped IN (0, 2)",
    ];

    if ($ref_search  !== '') { $s = $conn->real_escape_string($ref_search);  $where[] = "pp.RefSalesCode LIKE '%$s%'"; }
    if ($code_search !== '') { $s = $conn->real_escape_string($code_search); $where[] = "cm.customer_code LIKE '%$s%'"; }
    if ($part_search !== '') { $s = $conn->real_escape_string($part_search); $where[] = "im.part_number LIKE '%$s%'"; }
    if ($date_from   !== '') { $s = $conn->real_escape_string($date_from);   $where[] = "pp.req_date >= '$s'"; }
    if ($date_to     !== '') { $s = $conn->real_escape_string($date_to);     $where[] = "pp.req_date <= '$s'"; }

    if ($status_filter === 'pending')   { $where[] = "(COALESCE(pp.allocated_qty,0) = 0)"; }
    if ($status_filter === 'allocated') { $where[] = "COALESCE(pp.allocated_qty,0) >= pp.req_qty"; }
    if ($status_filter === 'partial')   { $where[] = "COALESCE(pp.allocated_qty,0) > 0 AND COALESCE(pp.allocated_qty,0) < pp.req_qty"; }

    $where_sql = implode(' AND ', $where);

    $cnt_res = mysqli_query($conn,
        "SELECT COUNT(pp.id)                                                                 AS total,
                SUM(CASE WHEN COALESCE(pp.allocated_qty,0) = 0 THEN 1 ELSE 0 END)           AS cnt_pending,
                SUM(CASE WHEN COALESCE(pp.allocated_qty,0) >= pp.req_qty THEN 1 ELSE 0 END) AS cnt_allocated,
                SUM(CASE WHEN COALESCE(pp.allocated_qty,0) > 0
                           AND COALESCE(pp.allocated_qty,0) < pp.req_qty THEN 1 ELSE 0 END) AS cnt_partial
         FROM   production_planning pp
         LEFT JOIN item_management   im  ON pp.part_id       = im.id
         LEFT JOIN inventory         inv ON inv.item_id       = im.id
         LEFT JOIN client_management cm  ON pp.customer_reff = cm.id
         WHERE  $where_sql"
    );
    if (!$cnt_res) { $response['message'] = mysqli_error($conn); echo json_encode($response); exit; }

    $cnt_row       = mysqli_fetch_assoc($cnt_res);
    $total_records = (int) $cnt_row['total'];
    $total_pages   = max(1, ceil($total_records / $per_page));

    $sql = "
        SELECT
            pp.id,
            pp.RefSalesCode,
            cm.customer_code,
            cm.id                        AS customer_id,
            pp.customer_reff,
            pp.req_date,
            pp.req_qty,
            COALESCE(pp.allocated_qty,0) AS allocated_qty,
            pp.status,
            pp.is_shipped,
            pp.item_price,
            pp.part_id,
            im.part_number,
            inv.quantity_in_stock
        FROM   production_planning pp
        LEFT JOIN item_management   im  ON pp.part_id       = im.id
        LEFT JOIN inventory         inv ON inv.item_id       = im.id
        LEFT JOIN client_management cm  ON pp.customer_reff = cm.id
        WHERE  $where_sql
        ORDER BY im.part_number ASC, pp.req_date ASC
        LIMIT  $per_page OFFSET $offset
    ";

    $result = mysqli_query($conn, $sql);
    if (!$result) { $response['message'] = mysqli_error($conn); echo json_encode($response); exit; }

    $rows = [];
    while ($row = mysqli_fetch_assoc($result)) $rows[] = $row;

    $part_ids_on_page = array_unique(array_column($rows, 'part_id'));
    $siblings_map     = [];

    if (!empty($part_ids_on_page)) {
        $ids_in  = implode(',', array_map('intval', $part_ids_on_page));
        $sib_res = mysqli_query($conn,
            "SELECT pp.id, pp.part_id, pp.req_date, pp.RefSalesCode,
                    pp.req_qty, COALESCE(pp.allocated_qty,0) AS allocated_qty,
                    (pp.req_qty - COALESCE(pp.allocated_qty,0)) AS remaining_need
             FROM   production_planning pp
             WHERE  pp.part_id    IN ($ids_in)
               AND  pp.is_shipped IN (0, 2)
               AND  pp.req_qty    > 0
             ORDER BY pp.part_id ASC, pp.req_date ASC, pp.id ASC"
        );
        if ($sib_res) {
            while ($s = mysqli_fetch_assoc($sib_res)) {
                $siblings_map[$s['part_id']][] = $s;
            }
        }
    }

    foreach ($rows as &$row) {
        $row['_siblings'] = $siblings_map[$row['part_id']] ?? [];
    }
    unset($row);

    $response['success']    = true;
    $response['data']       = $rows;
    $response['pagination'] = [
        'current_page'  => $page,
        'per_page'      => $per_page,
        'total_records' => $total_records,
        'total_pages'   => $total_pages,
        'showing_from'  => $total_records ? $offset + 1 : 0,
        'showing_to'    => min($offset + $per_page, $total_records),
    ];
    $response['summary'] = [
        'pending'   => (int) $cnt_row['cnt_pending'],
        'allocated' => (int) $cnt_row['cnt_allocated'],
        'partial'   => (int) $cnt_row['cnt_partial'],
    ];
}

echo json_encode($response);
exit;
?>