It may have been deleted.
Back to Products'; } else { $product_id = intval($product['product_id']); $type = $product['product_type']; $type_info = productTypes()[$type] ?? productTypes()['service']; $currency = (string) $product['product_currency_code']; $money = function ($amount) use ($currency) { return escapeHtml(billingMoney($amount, $currency)); }; $archived_at = $product['product_archived_at']; $tracked = intval($product['product_track_stock']) === 1; $on_hand = floatval($product['product_stock']); $reorder_level = floatval($product['product_reorder_level']); $reorder_qty = floatval($product['product_reorder_qty']); $needs_reorder = $tracked && !$archived_at && $on_hand <= max($reorder_level, 0); $margin = productMargin($product['product_price'], $product['product_cost']); $billed = productBilledText($product['product_frequency'], $product['product_seat_source']); $period = $product['product_frequency'] ? ' a ' . recurringInvoicePeriodWord($product['product_frequency']) : ''; $can_edit = lookupUserPermission('module_sales') >= 2; $can_delete = lookupUserPermission('module_sales') >= 3 && !empty($config_destructive_deletes_enable); $csrf = $_SESSION['csrf_token']; // Hardware - the client asset it becomes when sold, and the ones it became $asset_type = $type === 'product' ? (string) $product['product_asset_type'] : ''; $warranty_months = intval($product['product_warranty_months']); $can_see_assets = lookupUserPermission('module_support') >= 1; $assets = $can_see_assets ? productAssets($product_id, 200) : []; $asset_clients = count(array_unique(array_column($assets, 'client_id'))); // Its price over time, and the lines still at an old price $prices = productPrices($product_id, 100); $last_change = productPriceLastChange($product_id); $behind = productRepriceCount(['product_id' => $product_id]); $usage = productUsage($product_id); $moves = $type === 'product' ? productStockMoves($product_id, 200) : []; $history = auditLogHistory('Product', $product_id); $sold = $usage['sold']; // Recurring first for what is billed each month, quarter or year, invoices first for the rest $tabs = [ 'recurring' => ['label' => 'Recurring', 'icon' => 'fa-redo-alt', 'count' => count($usage['recurring'])], 'invoices' => ['label' => 'Invoices', 'icon' => 'fa-file-invoice-dollar', 'count' => count($usage['invoices'])], 'quotes' => ['label' => 'Open quotes', 'icon' => 'fa-comment-dollar', 'count' => count($usage['quotes'])], 'prices' => ['label' => 'Prices', 'icon' => 'fa-tags', 'count' => count($prices)], 'history' => ['label' => 'History', 'icon' => 'fa-history', 'count' => $history['count']], ]; if (!$product['product_frequency']) { $tabs = ['invoices' => $tabs['invoices'], 'quotes' => $tabs['quotes'], 'recurring' => $tabs['recurring'], 'prices' => $tabs['prices'], 'history' => $tabs['history']]; } // The client assets made from it, after the invoices it was sold on if ($can_see_assets && ($asset_type !== '' || $assets)) { $with_assets = []; foreach ($tabs as $tab_key => $tab) { $with_assets[$tab_key] = $tab; if ($tab_key === 'invoices') { $with_assets['assets'] = ['label' => 'Assets', 'icon' => 'fa-laptop', 'count' => count($assets)]; } } $tabs = $with_assets; } // Its stock moves - first for a product that tracks stock if ($tracked || $moves) { $stock_tab = ['stock' => ['label' => 'Stock', 'icon' => 'fa-warehouse', 'count' => count($moves)]]; $tabs = $tracked ? $stock_tab + $tabs : $tabs + $stock_tab; } $stock_url = function ($mode) use ($product_id) { return "modals/product/product_stock.php?id=$product_id&mode=$mode"; }; // Override Tab Title // No Sanitizing needed as this var will only be used in the tab title $page_title = $product['product_name']; ?>