Files
itflow/admin/database_updates/2.9.1.php
johnnyq 422088fb60 Invoices, quotes and recurring invoices makeover stage 2: per user, per device and per license recurring lines that take their quantity from the client's contacts (all or tagged), devices (ticked types or tagged, lost/stolen/retired left out) or a license's seats (in use or bought), counted again for every invoice with an optional contract minimum, set from a Counted choice on the add row or the full Quantity from section in Edit Line with a live count, marked on each line and listed in a new Seats card with Update now when the client has changed, quarterly frequency alongside monthly and yearly counted as a third in MRR on the dashboard, client pages, client portal and reports, period words {month} {quarter} {year} {period} filled into scope, notes and lines, schedule card showing the period the next invoice covers, recurring_invoice_anchor_day so month-end schedules return to the 31st after a short month, nightly run and Invoice Now consolidated into recurringInvoiceGenerate() which claims the run so it is billed once, refreshes seat counts and takes taxes at current rates, nightly run now bills runs missed by up to 7 days, Invoice Now bills the next run early and moves the schedule on from that run instead of restarting from today, recurring email goes to non-archived primary and billing contacts once per address and stays a draft when outgoing mail is not set up. Fixes portal recurring card ignoring yearly-only clients and counting archived ones, edit recurring invoice resetting the billing day. Adds DB 2.9.1, recurring_invoice_sync and recurring_seat_count handlers, itflowBillingSeatForm(), and updates the 26.11 changelog
2026-10-16 13:09:59 -04:00

25 lines
1.4 KiB
PHP

<?php
/*
* ITFlow - Database update to version 2.9.1 (from 2.9.0)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Seat-based lines on recurring invoices (functions/billing.php). A line
// can take its quantity from the client - their contacts, their devices
// (of some types), or a license's seats - counted again each time an
// invoice is made, never less than its minimum. item_seat_filter holds
// what to count, as JSON.
mysqli_query($mysqli, "ALTER TABLE `recurring_invoice_items`
ADD COLUMN `item_seat_source` varchar(20) DEFAULT NULL AFTER `item_product_id`,
ADD COLUMN `item_seat_filter` varchar(1000) DEFAULT NULL AFTER `item_seat_source`,
ADD COLUMN `item_seat_minimum` decimal(15,2) NOT NULL DEFAULT 0.00 AFTER `item_seat_filter`");
// The day of the month a recurring invoice bills on, so a schedule on the
// 31st comes back to the 31st after a shorter month instead of drifting
// to the 28th for good. Existing ones keep the day of their next date.
mysqli_query($mysqli, "ALTER TABLE `recurring_invoices` ADD COLUMN `recurring_invoice_anchor_day` tinyint(2) NOT NULL DEFAULT 0 AFTER `recurring_invoice_next_date`");
mysqli_query($mysqli, "UPDATE `recurring_invoices` SET `recurring_invoice_anchor_day` = DAY(`recurring_invoice_next_date`) WHERE `recurring_invoice_next_date` IS NOT NULL");