= $template['product_name'] !== null ? 'The product it is sold as,
' . escapeHtml($template['product_name']) . ', is archived.' : 'It isn\'t sold as a product yet.' ?>
Pick the product it is sold as on the template, then bill its licenses from here.
= $picked ? 'Every one of them is billed already.' : 'No licenses made from it yet.' ?>
= productTile($template['product_name'] !== null ? (string) getFieldById('products', $product_id, 'product_type') : 'service') ?>
= escapeHtml($template['product_name']) ?>
= escapeHtml(softwareTemplatePriceText($template)) ?>
The line's quantity follows the license each time an invoice is made. One with no seat limit counts the seats in use.
| Client | Seats | Recurring invoice |
$row) {
$client_id = intval($row['software_client_id']);
$options = $recurring[$client_id] ?? [];
// An active one billed as often as the product, then any active one, then the first
$default = 0;
foreach ($options as $recurring_id => $option) {
if (intval($option['recurring_invoice_status']) === 1 && $option['recurring_invoice_frequency'] === (string) $template['product_frequency']) {
$default = $recurring_id;
break;
}
}
$default = $default ?: (int) array_key_first($options);
?>
| > |
= escapeHtml($row['client_name']) ?>
= escapeHtml($row['software_name']) ?>
|
= $row['seats']['total'] > 0 ? $row['seats']['total'] . ' bought' : 'No limit' ?> = $row['seats']['used'] ?> in use |
No recurring invoice - make one first
|
= count($billed) === 1 ? '1 of the ones picked is' : count($billed) . ' of the ones picked are' ?> billed already, so not here.