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;
}