diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b8ae3ac..302d3c5b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,9 @@ This file documents all notable changes made to ITFlow. ### Upgrading to 26.11 -Update from Maintenance > Update — Queue Update hands the job to cron, which updates the files and applies this release's database changes (2.7.9 to 3.2.8) in the same pass. Nothing else is required. +Update from Maintenance > Update — Queue Update hands the job to cron, which updates the files and applies this release's database changes (2.7.9 to 3.2.9) in the same pass. Nothing else is required. -This is a big release, with forty-nine database steps in one go, so take a backup before you update. +This is a big release, with fifty database steps in one go, so take a backup before you update. The update also clears out data that deletes in older versions left behind, all of it pointing at something that no longer exists: @@ -49,7 +49,7 @@ Canned responses keep their names, what they say and their ticket category. One Document templates keep their names, summaries, what they say and their images. Words in square brackets already in them are now filled in when a document is made: [Client], [Site], [Contact], [Date] and the others listed under New Features (Document templates) from the client, and the rest are asked for as plain, optional text until you set them up on the template's page - one left blank stays as it is, as before. Documents made from a template before the update don't know which one, so a template's use is counted from the update - link one to its template from the document's page to count it. No template is required of anyone, and none asks for reviews, until you set it up on its page. The starter document templates you added from Maintenance > Starter Content stay as they are; Update on that page brings them up to the new versions, which fill in from the client, ask for what they need and are reviewed on a schedule. -License templates keep everything they hold. A license called exactly what one license template is called - as the New License form named it when started from one - counts as made from that template, so a template's use starts out counted; where two templates share a name, neither is given its licenses. Other licenses don't know a template, so they count from the update. +License templates keep everything they hold. A license called exactly what one license template is called - as the New License form named it when started from one - counts as made from that template, so a template's use starts out counted; where two templates share a name, neither is given its licenses. Other licenses don't know a template, so they count from the update. No template sets seats, a renewal term, a vendor or a product until you give it one. If you are coming from 26.08 or earlier, the database update still has to be run from the command line one time, exactly as described under Upgrading to 26.09 below. @@ -552,6 +552,12 @@ If you are coming from 26.08 or earlier, the database update still has to be run - Templates can be copied, archived - not offered on New License, while the licenses made from them stay - restored and deleted. - The template window has its icons, a summary and room for the notes every license from it should carry. - A license started from a template on New License remembers it, and its quick look says which template it came from. + - A template can carry the seats a license starts with, how often it renews, its vendor - picked from the vendor templates - and the product in Products & Services it is sold as. The page and the list show them, and the list finds a template by its vendor or product. + - A license made from one starts with its seats, and its renewal date is worked out from when it was bought - a year on for a yearly one, or from today when there is no purchase date. Its vendor is the client's own one made from the vendor template, or one of that name; a client without it has it added from the vendor template, by anyone who can add vendors. + - On New License, picking a template fills in its seats, vendor and renewal date as well, and the renewal date follows the purchase date until you type one in. A vendor you picked yourself stays. + - Renew starts on the template's term for licenses made from it. + - New licenses for several clients at once, from the template's page or the list: pick the clients, skip the ones that already have one, and give the seats, dates and order reference once. + - A license's quick look shows the product it is sold as, with its price, to anyone who can see Sales. - **Assets** - The asset list has: - type icons, colored status pills and OS icons @@ -1547,6 +1553,10 @@ If you are coming from 26.08 or earlier, the database update still has to be run - New `functions/software_template.php`: `softwareTemplateRow($id)` (with `created_by_name` and `updated_by_name`), `softwareTemplateUsage($ids)` (`count`, `clients`, `seats`, `used`, `renewing`, `expired`, `last` - current licenses of current clients), `softwareTemplateFields($post, &$error)`, `softwareTemplateSave($id, $fields)`, `softwareTemplateCopy($id)`, `softwareTemplateDelete($id)` (clears the template from its licenses, leaving `software_updated_at` alone), `softwareTemplateLiveId($id)` and `softwareTemplateMakeLicense($id, $client_id, $post)` (through `softwareFormSet()`). - Admin: `admin/software_templates.php` takes `q`, `sort` - `software_template_name`, `software_template_type`, `software_template_license_type`, `used_count`, `last_used` or `changed_at` - `order`, `page` and `show=archived`; new `admin/software_template.php` (`software_template_id`). `admin/modals/software_template/software_template_form.php` is shared by `software_template_add.php` and `software_template_edit.php` (`id`); new `software_template_use.php` (`id`, `client_id`) posts `add_software_from_template` to `agent/post.php`. `admin/post/software_template.php`: `add_software_template` (redirects to its page), `edit_software_template`, GET `copy_software_template`, `archive_software_template`, `restore_software_template` and `delete_software_template` (`from_page`). Audit entries are Software Template Create, Edit, Archive, Restore and Delete. - Agent: `add_software` keeps the `software_template_id` the New License form posts when it is a current template. `add_software_from_template` makes the license with `softwareTemplateMakeLicense()` - `seats`, `key`, `purchase`, `expire` and `purchase_reference` - checks the client and redirects to `/agent/software.php?client_id=`. The license quick look shows the template. + - Database 3.2.9: `software_templates.software_template_seats` (null for no limit), `software_template_term` (a `SOFTWARE_RENEWAL_TERMS` key, or null), `software_template_vendor_template_id` and `software_template_product_id` (0 for none). + - `functions/software_template.php`: `softwareTemplateRow()` also returns the vendor template's name and archived date and the product's name, price, cost, currency, frequency, seat source and archived date; `softwareTemplateFields()` reads `seats`, `term`, `vendor_template_id` and `product_id` (one that exists, archived or not); new `softwareTemplateLinkId($table, $column, $id)`, `softwareTemplateRenewal($term, $purchase)`, `softwareTemplatePriceText($template)`, `softwareVendorFromTemplate($vendor_template_id, $client_id, $make = true, &$made)` (the client's vendor made from it, then one of its name, then - with `$make` - one made through `vendorFormSet()`) and `softwareTemplateMakeForClients($id, $client_ids, $post, $skip_existing = true, $make_vendor = true)` (`made`, `skipped`, `vendors`). `softwareTemplateMakeLicense($id, $client_id, $post, $make_vendor = true, &$vendor_made)` takes the template's seats when `seats` isn't posted and its term from `purchase` when `expire` is blank. + - Admin: new `admin/modals/software_template/software_template_use_several.php` (`id`) posts `make_licenses_from_template` (`client_ids[]`, `skip_existing`, `seats`, `purchase`, `expire`, `purchase_reference`) to `admin/post/software_template.php`, which redirects to the template's page. Deleting a vendor template or a product (`productDelete()`) clears it from the license templates that had it, leaving `software_template_updated_at` alone. + - Agent: the New License form's templates carry `seats`, `term`, `vendor_template_id` and `vendor`; the vendor picker is `data-software-vendor` (with `data-vendor-can-make` for someone with `module_client` 2) and its options `data-vendor-template-id`. `add_software` takes `vendor=template:N`, made with `softwareVendorFromTemplate()` when the agent has `module_client` 2. `add_software_from_template` and `make_licenses_from_template` audit a vendor they made as Vendor Create. The Renew window starts on the template's term when the licenses share one. - Empty states: every list page sets `$empty_state` before including `includes/filter_footer.php`, and `includes/inc_empty_state.php` draws it with `emptyStateHtml()` (`functions/format.php`) when the list has nothing - `thing`, `icon`, `title`, `text`, `actions` (`label`, `modal` or `href`, `size`, `icon`; the first is the main one), `archived`, `view`, `filtered`, `views`, `match_title`, `match_text` and `clear_url`. `emptyStateFiltered($views)` reads the GET string for a search or filter, leaving out paging, sorting, `client_id`, `archived` and the page's views, and `emptyStateClearUrl($views)` is the page without them. `emptyStatePill($pills, $key, $default, $good)` builds a pill's own state from the page's pill array (`label`, `icon`, `title`, `alarm`), with a tick for `alarm` pills and the keys in `$good`. Files, notifications and racks call `emptyStateHtml()` in their own layout; files and notifications set `$empty_state_skip`. A page that sets nothing still gets one, worded from `$page_title`. The pages' own empty blocks (`.itflow-asset-empty` under a list) are gone. CSS: `.itflow-empty-state` with `-icon` (a grey round tile), `-title`, `-text` and `-actions`. - Removed unused helpers and files: - `credentialLink()`, `projectLink()`, `linkCounts()`, `assetContactAvatar()`, `clientOverviewPersonInitials()`, and `getMonthlyTax()` and `getQuarterlyTax()`, which looked a tax up by name diff --git a/admin/database_updates/3.2.9.php b/admin/database_updates/3.2.9.php new file mode 100644 index 000000000..2c459276c --- /dev/null +++ b/admin/database_updates/3.2.9.php @@ -0,0 +1,17 @@ +