Skip to content
← Back to Functions
Code

Inventory Aging Report

Groups products or assets by age, status, and activity.

Function signature

ogBuildInventoryAgingReport(items = array(), options = array())

Categories

  • File and Upload Safety

Parameters

itemsItem records with created_at, last_activity_at, and status keys.optionsOptions: as_of timestamp and bucket day limits. Recognized keys: `as_of`, `buckets`.

Return value

Short public-safe status message.

  • buckets
  • status_counts
  • item_count

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, policy arrays, URLs, signatures, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Groups inventory or catalog records into age buckets.
 *
 * @param array $items Item records with created_at, last_activity_at, and status keys.
 * @param array $options Options: as_of timestamp and bucket day limits.
 * @return array Inventory aging report.
 */
function ogBuildInventoryAgingReport($items = array(), $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	if (!is_array($items)) {
		$result['message'] = 'Items must be an array.';
		return $result;
	}

	if (!is_array($options)) {
		$options = array();
	}

	$as_of = time();
	if (!empty($options['as_of'])) {
		$as_of = strtotime((string)$options['as_of']);
		if (empty($as_of)) {
			$as_of = time();
		}
	}

	$buckets = array(30, 60, 90, 180, 365);
	if (!empty($options['buckets']) && is_array($options['buckets'])) {
		$buckets = array();
		foreach ($options['buckets'] as $bucket) {
			$bucket = (int)$bucket;
			if ($bucket > 0) {
				$buckets[] = $bucket;
			}
		}
		sort($buckets, SORT_NUMERIC);
	}

	$report = array();
	$status_counts = array();
	foreach ($items as $item) {
		if (!is_array($item)) {
			continue;
		}

		$created = $as_of;
		if (!empty($item['created_at'])) {
			$created = strtotime((string)$item['created_at']);
			if (empty($created)) {
				$created = $as_of;
			}
		}

		$age_days = (int)floor(($as_of - $created) / 86400);
		if ($age_days < 0) {
			$age_days = 0;
		}

		$label = 'over-' . end($buckets) . '-days';
		foreach ($buckets as $bucket) {
			if ($age_days <= $bucket) {
				$label = '0-' . $bucket . '-days';
				break;
			}
		}

		$status = 'unknown';
		if (!empty($item['status'])) {
			$status = strtolower(trim((string)$item['status']));
		}

		if (empty($report[$label])) {
			$report[$label] = 0;
		}
		$report[$label]++;

		if (empty($status_counts[$status])) {
			$status_counts[$status] = 0;
		}
		$status_counts[$status]++;
	}

	$result['success'] = true;
	$result['message'] = 'Inventory aging report built.';
	$result['data'] = array(
		'buckets' => $report,
		'status_counts' => $status_counts,
		'item_count' => count($items)
	);

	return $result;
}