Where could this relatively complex page method go to avoid recalculating

A while ago I wrote this relatively complex, not very efficient, page method.

Now I am using it in a pages table layout column value, but that takes a while to calculate for each page.

Other than refactoring, where can this code go to avoid recalculating on every call?

    ...
	'isowed' => function () {
		$products = $this->allTheirProducts();
		$owed = 0;
		if (count($products) > 0) {
			foreach ($products as $product) {
				$productArray = [];
				$sold = 0;
				foreach (page('orders')->children() as $order) {
					foreach ($order->items()->toStructure() as $item) {
						if ($item->id() == $product->id()) {
							$sold += 1;
						}
					}
				}
				if ($sold > 0) {
					$productArray['id'] = $product->id();
					$productArray['sold'] = $sold;
					$productPrice = $product->price()->toFloat();
					$productTax = $productPrice / 100 * site()->tax()->toFloat();
					$productionAndPackagingPrice = site()->productionandpackaging()->toFloat();
					$productNetPrice = $productPrice - $productTax - $productionAndPackagingPrice;
					$productArray['total'] =  (($productNetPrice * $sold) / 100) * site()->artistpercent()->toFloat();
					$owed += $productArray['total'];
				}
			}
			
		}
		return $owed;
	},
    ...

Would placing it in a page model help, or that is just a way to organize methods by template?

How about storing the result of this calculation in the page itself via a hook on update? Then you only need to call the method from your hook, and you don’t have to implement any caching routines. Seem to me to be the fastest and easiest to implement.

Yes, I think that is what makes more sense.

Can we safely store fields on a page through update, that do not exist in the blueprint?

Thanks

yes. unless you run a cleaning script your additional data will stay content file.

Ah yes, good call.

I suppose a hidden field could be a safer option?

thanks

Yep