johnnyq
d6e6bd146b
Products makeover stage 2: inventory ledger and alerts - every stock change recorded through productStockMove as received, sold, returned, counted or written off with unit cost, invoice or expense, note and agent, one Stock window to Receive, Count or Write off replacing Add Stock, a Stock tab on the product page with a running balance, Reorder at and Order per product with a To reorder tab, list and side nav badges, a dashboard Needs attention item and Low Stock notifications, a Count Stock page with live differences and a printable count sheet, an Inventory report with CSV exports, reorder columns and stock value in import and export, cancelling or deleting an invoice returns its stock from the net of its moves, copying an invoice or invoicing a quote carries the product link and is refused when tracked stock is short, recurring generated invoices link their products without moving stock, decimal stock quantities, database 2.9.5 with stock type, unit cost, invoice and user columns backfilled from existing notes, CHANGELOG updated
2026-10-16 15:48:29 -04:00
johnnyq
775edc53d8
Products makeover stage 1: products and services with cost and margin, the vendor they are bought from with its part number, internal notes and default billing of one time, monthly, quarterly or yearly per user or per device that fills in Billed on quotes and Counted on recurring invoices, a per-product Track stock switch so only tracked items move stock and refuse to be invoiced past the shelf while untracked ones are ordered as needed, rebuilt Products list with what catalog lines bring in each month on recurring, sales over 90 days with the top seller and stock value at cost, tabs for Services, Products, Recurring and Stocked, a vendor filter and part number search, a new product page with price, margin, 12 month sales, monthly recurring, stock with recent moves, recurring invoices, open quotes, invoices and history tabs, inline notes and Copy, one New and Edit window with live margin, rebuilt Add Stock, import by column heading with update by code for price lists, export with cost, margin, billing, vendor, part number and stock, agent-only margin on invoices, quotes and recurring invoices, a Products tab on our vendors' pages, search results opening the product page, billing defaults in the starter catalog and costs and vendors in the demo data. Fixes bulk Restore of archived products doing nothing, deleted products leaving stock behind, Add Stock recording zero units or a missing expense, and a backslash before an apostrophe in agent names in billing history. Adds DB 2.9.4 with product cost, vendor, part number, notes, frequency, seat source and track stock set for products with stock history plus product keys on line and stock tables, functions/products.php with productSave() as the one write path, productUsage() and billingMargin(), agent/product.php, a shared product_form.php, copy_product and product_set_notes handlers, removes product_model.php, and updates the 26.11 changelog
2026-10-16 15:23:05 -04:00
johnnyq
3ec52974db
Calendar modernization: calendar page rebuilt to load only the dates on screen with show or hide toggles for each calendar and for built-in sources (scheduled tickets, project start and due dates, service reviews, recurring tickets, renewals, invoices due), a filter for one agent, quick looks on click, drag to reschedule tickets and events that do not repeat, and a To schedule panel for dragging open unscheduled tickets onto the calendar; events get a shared add/edit form with repeats every N days/weeks/months/years with an optional end date and single skipped occurrences, a client site, location or meeting link, agents, client contacts and guest emails as attendees, iCalendar invitations with updates and cancellations sent to invited attendees, an event quick look with map and join links, .ics download and resend; each agent gets a personal subscription link for their schedule (their own or the whole team, busy only option, respects role and client access, stops when the account is disabled) with setup help for Google, Outlook, Apple, Nextcloud and Thunderbird; shared calendar feeds and invites now publish timed events with TZID and VTIMEZONE so repeating events keep their time across DST, with INTERVAL, UNTIL and EXDATE support; managing calendars is limited to admins; ticket schedule logic moved into functions/ticket.php and shared with the calendar, the schedule dialog shows the assigned agent's day, and ticket visit calendar files are rebuilt without zapcal as one-hour published events; mail queue sends invitations and cancellations as a text/calendar part and other calendar files as invite.ics; dashboard schedule shows only events the agent is on or added, client overview Coming up and client sidebar count use upcoming events, sites and contacts get New event shortcuts, demo data uses repeating events and attendees; database update 2.8.8 adds event repeat interval, until, skip, sequence and created by, attendee user and invited at, user_calendar_feeds, and widens email_queue.email_cal_str to text
2026-10-15 19:17:17 -04:00
johnnyq
ade9d5aac3
Services modernization: new services list with Needs attention, Review due, High importance, No review set, Starred and Archived views, dependency chips, in-place importance, bulk importance/category/review schedule, mark reviewed, star, archive/restore/delete and CSV/PDF export; new service page with service facts, backup and recovery, who to call (vendor and client contact details), auto-saving notes and tabs for the assets it runs on, logins, domains and certificates, documents, tickets and history; compact quick look; shared add/edit form with importance, category suggestions, a review schedule and dependency pickers on add; review modal with checklist and history note; attention flags for expiring or expired domains and certificates, certificate check problems, infrastructure out of warranty or out of action, and archived records still linked; Report a problem opens a prefilled ticket linked to the service, plus a service_tickets table, ticket page services list and link/unlink from both sides; services, domains and certificates added to the generic link system, legacy service link actions routed through it with same-client checks; services shown on the asset, contact and vendor pages, the asset/domain/certificate/credential quick looks, the document Linked card, the client overview (card, attention items, upcoming reviews), the dashboard, calendar, global search, client PDF pack and nightly review notifications; archived services left out of nav counts and lookups; services read endpoint in the API; demo data review schedules; database update 2.8.7 (archive and review columns, wider category and backup, link table dedupe with primary keys, service_domains foreign keys, service_tickets)
2026-10-15 17:32:09 -04:00
johnnyq
64d938db7f
Tickets modernization: list redesign with Open/Mine/Unassigned/Needs reply/Waiting/Overdue/Scheduled/Closed/All views, whose-move indicator, SLA and due badges, in-row status/priority/agent pickers, collapsible filters and phone layout; kanban board redesign with drag-to-resolve/reopen rules and dark mode; new ticket quick look modal; New Ticket modal with asset/contact prefill and already-open warning; Edit Ticket modal rework; recurring tickets list rework with pause/resume, raise now, plain-language schedules, next-run preview and bulk actions, cron skips paused and raises missed runs once; shared ticket tables on asset/contact/location/vendor/project pages; Also open card on ticket detail; portal waiting-on-your-reply status; merge limited to same client; closed tickets no longer editable from modals or API; consistent access checks across ticket modals, post handlers and ajax endpoints; new functions/ticket.php helpers; removed recurring_ticket_model.php; DB 2.8.5 adds recurring_ticket_paused_at and cleans orphaned recurring ticket rows
2026-10-15 15:29:10 -04:00
johnnyq
e4c8130ebe
Certificates: Check now connects to the host and saves what it serves - issuer, issued and expiry dates, names covered, SHA-256 fingerprint and the PEM - with the result (OK, name mismatch, untrusted, expired or unreachable) and when it ran, and a check that reaches nothing keeps the certificate on file; New/Edit form split into tabs (Certificate, Paste or by hand, Notes) with a Check button that shows what the host serves before saving, the host tidied from a pasted web address, the name defaulting to the host, the domain picked from the host and limited to the client's own, and a PEM paste or issuer and expiry by hand for hosts ITFlow can't reach; new certificate quick look with the check result and what to do about it, names covered, fingerprint copy, PEM copy and .crt download, domain, services, notes and history; certificates list rebuilt with All/Starred/Expiring soon/Expired/Problems/Not checked pills, host and names covered, domain link, issuer filter, last check column, whitelisted sort, ?open= and bulk check/star/archive/restore/delete; short-lived (ACME) certificates only count as expiring soon inside 20 days and skip the 45-day alert; domain and service quick looks link certificates to their quick look (with New certificate from a domain), global search finds certificates by name, host, names covered or fingerprint, client overview gets a Certificate problems box and renewals open the certificate, dashboard links to Expiring soon, client portal shows expiry badges, export adds last check, names covered, fingerprint and more, documentation PDF adds host and last check; certificate refresher now checks hosts daily in a time-boxed batch, writes history and notifies when an OK certificate turns bad; nightly alerts skip archived certificates and open the certificate; API create uses the same form rules and checks the host; demo data adds firewall, remote access and RADIUS certificates with real check results. Fixes the delete audit log using an undefined name, the archive flash type, certificates linking to another client's domain, services linking to another client's certificates, PEM parsing assuming an issuer organisation, and the API create using an undefined variable. DB 2.8.4
2026-10-15 01:07:32 -04:00
johnnyq
75df17698b
Domains makeover: rebuilt domains list with expiry pills (red expired, amber close, blue close but auto-renewing), registrar and hosts shown once per vendor with their roles, SPF/DMARC/DKIM email pills, filters for Starred, Expiring in 45 days, Expired, No auto-renew and Email gaps with counts, registrar-or-host and tag filters, search across notes, hosts and tag names, safe column sorting, open straight to a domain with ?open=ID; new domain quick look with expiry, auto-renew, registration date and status, who registers it and hosts DNS, website and email, A/NS/MX records to copy, plain-language email checks (SPF strictness and duplicates, DMARC policy, DKIM at common selectors), certificates, services, the registrar and host logins, notes, TXT records, raw WHOIS and history; tabbed add/edit form that tidies pasted addresses to the domain, checks the name as it is typed (saved as, subdomain, already on the client), auto-renew switch, star, tags, client and our own vendors as registrar and hosts, Registrar does it all; add several domains at once from a pasted list; bulk look up now, set registrar or host, tags, star and unstar; domain tags (tag type 7) with a starter pack; refresher looks up a batch of up to 50 a run, never-checked, stale and soon-to-expire first; expiry alerts skip archived domains and clients, mention auto-renew and open the domain; vendor Domains tab opens the quick look and adds a domain with that vendor as registrar, our vendors get a Client domains tab; service quick look, overview renewals and search open the domain; client portal shows days to expiry and auto-renew; more export columns and filters; demo data with auto-renew, varied DMARC and DKIM, WHOIS lines and campaign domains near expiry. Fixes lookups, edits, the refresher and API updates wiping expiry dates and records when a lookup came back empty, edits logged without a client and dropping a past expiry date, every edit running slow lookups, expiry alerts for archived domains, deleted domains left on services and certificates, bulk archive needing delete rights and list actions limited to admins, registrar and host pickers accepting another client's vendors and dropping our own on save, services linking other clients' domains, a new client's website domain not added when its expiry could not be found, the WHOIS summary cut at 254 characters, and API names, vendors and duplicates not checked. Adds functions/domain.php helpers, domain quick look and shared form, domain_check lookup; removes domain_model.php. DB 2.8.3
2026-10-15 00:09:09 -04:00
johnnyq
fecd1cabff
Credentials makeover: rebuilt credentials list with kind icons, username copy, password show/copy and live 2FA code buttons fetched on demand, where it opens, what it is for (asset, contact, vendors, licenses, services), password age pills and last used, filters for Starred, With 2FA, No 2FA, Not changed in 90 days and Shared with counts, search across notes, second link, tags, asset and contact, open straight to a credential with ?open=ID; new credential quick look with login, age, last viewed by, links with unlink, notes, open share links with turn off, and history; tabbed new/edit form with password generator (passphrase or random), strength meter, 2FA secret that accepts spaces or an otpauth:// link and shows the current code to check, copy buttons on both links, prefill from asset, contact or vendor; new Change password window that dates and logs the change; new Share window from anywhere (contact or email, 1 hour to 1 month, gone after opened once by default, link copied); same login controls on asset and contact pages and quick looks, vendor Logins tab, license page and quick look, service quick look, client overview favourites and search; credential pickers show icons and say when a credential moves from another asset or contact; client overview Passwords due for a change attention item and Active share links limited to live links; rotation report with selectable span, per client counts and oldest first; more export columns; demo data gets 2FA secrets, varied password ages and logins attached to their assets. Fixes passwords being blanked when the vault session had expired, other clients' assets, contacts and tags accepted on save, bulk star using the wrong permission, credential links to assets and contacts not checking the client, the edit or link permission, or which asset or contact an unlink was for, credentials left pointing at deleted assets and contacts, share links left open after a credential was deleted, import carrying values between rows and accepting any file type, 2FA secrets saved with spaces or lowercase giving no code, the service quick look listing credentials without credential access and repeating assets, an asset login with only a username being lost, and the API not dating new passwords. Adds functions/credential.php and js/credentials.js; removes credential_model.php and the old credential show password/OTP scripts. No DB change.
2026-10-14 23:33:29 -04:00
johnnyq
9e55d52432
Vendors overhaul for daily MSP work: new vendor page built around calling them, with Call support (dials the extension), Email, Support site, a star, and a New menu (case/ticket with them, license from them, asset bought from them, portal login, document, upload, or expense and recurring expense for our own vendors), Support card (phone, hours, SLA, email, site), Account card (account number, PIN shown as dots with show and copy, account manager name, direct line and email), blur-to-save notes, an Also used by list of the agent's other clients with the same vendor by name or template, and tabs for Cases (open first, with their ticket number), Licenses (soonest renewal first), Assets (serial, order ref, warranty status), Domains (registrar, web host, DNS, mail), Services, Logins, Documents, Files and History; our own vendors show spend this year, last year and in all, recent expenses and recurring expenses; new vendor quick look; rebuilt vendors list with starred first, initials tiles coloured by vendor name, support line, hours and SLA, account number and PIN, chips for open cases, licenses, assets, domains, services and logins, an Ours / Clients' switch with an all-clients view in All Client Docs, wider search (account manager, emails, tags), tag filter and bulk Tags/Archive/Restore/Delete; shared tabbed vendor form (Details, Support, Account, Notes) with star, tags and start from template that fills every field; Add a Template to Clients to roll one vendor out to many clients, skipping those that have it; Admin Vendor Templates shows how many clients use each template and has Add to clients; vendor tags (tag type 6) with vendor tags in the Tags starter pack; ticket vendor block shows their ticket number, support line, hours, SLA, account number and PIN with copy buttons; vendor tiles in every vendor picker and quick look links across tickets, licenses, assets, domains, services and expense lists; search opens the vendor page; CSV export adds tags, open cases, account manager and PIN; logins, documents and files can be linked to a vendor and ones made from a vendor's page are linked to it; demo vendors get tags, a star and an account manager; database update 2.8.2 adds vendor_tags and vendor_contact_phone_country_code, vendor_contact_phone, vendor_contact_email (db.sql updated) and clears references to vendors that no longer exist; ticket vendor now validated against the ticket's client and removing a vendor from a ticket is logged as such; deleting a vendor from a template no longer unlinks every other vendor from that template; deleting a vendor clears it from assets, licenses, tickets and domains, and vendors with expenses, recurring expenses or payment provider fees are archived rather than deleted; vendor websites without a scheme open correctly; domain form vendor names escaped; new vendor templates keep the phone country code and pushing a template update with nothing ticked no longer errors; vendors API accepts the account manager fields; new functions/vendor.php (VENDOR_USES, vendorCan/vendorEnforce with client vendors on module_client and ours on module_financial, tile, link, website, PIN, form, tags, counts, delete check, reference clearing, also used by, spend, history), credential|vendor and file|vendor link relations, tag module_ours for our own vendors, handlers add_vendor_template_to_clients, favorite_vendor, unfavorite_vendor and ajax vendor_set_notes, vendor_model.php removed
2026-10-14 22:49:05 -04:00
johnnyq
57b8ced839
Locations overhaul for daily MSP work: new location page with header actions (Directions, Call, New ticket/contact/asset/network/rack/document/upload/trip prefilled to the location, Move here, Edit, Make primary, Archive/Restore/Delete), Getting there / Ask for / blur-to-save Access notes panels, and People, Assets, Networks, Racks, Tickets (open first), Documents, Files and History tabs with per-record unassign and remembered tab; new location quick look modal (glance, directions, access notes, People/Assets/Networks/Open tickets tabs); new Move here modal to bulk-move contacts, assets, networks and racks to a location showing where each currently is; rebuilt locations list with primary-first sort, photo/pin tile, maps link and Directions button, phone and hours, on-site contact, On site count chips linking to the location page tabs, wider search (phone, notes, contact, tags) and bulk Tags/Archive/Restore/Delete; shared tabbed location form (Details, Address, Contact, Access) with Primary switch, auto-primary for a client's first location, tags and photo removal; ticket detail Site card with address, phone, hours, access notes and directions; ticket location now validated against the ticket's client; documents and files can be linked to locations via new location_documents and location_files tables (database update 2.8.1, db.sql updated) and the generic link modal; location results in global search; client header primary location, network and rack pages link to the location; CSV export adds Primary, On-site Contact, people/asset counts and Access Notes, CSV import checks the file extension and makes the first location primary; primary locations cannot be archived or deleted and bulk archive skips them; deleting a location (including via API) clears its references on assets, contacts, networks, racks, tickets and calendar events; new functions/location.php helpers (LOCATION_KINDS, address/map/directions URLs, tile, counts, form set, tags, primary, photo, assign/unassign, history), new handlers make_location_primary, set_location_records, unset_location_record and ajax location_set_notes, location_model.php removed, demo data gets an on-site contact and linked runbook for the primary location
2026-10-14 22:06:41 -04:00
johnnyq
2d6e40bcf6
Racks makeover: rack page with to-scale front/rear elevation (click an empty U to add), front/rear mounting and full/half depth, non-asset items (patch panel, cable management, shelf, PDU, UPS, KVM, blanking panel), item edit/move, U and power capacity with largest free gap, front/rear photos, U1 top/bottom numbering, print view, Not racked yet list, rack cards with mini elevation and usage, Racks under All Client Docs, rack position on asset views. Fixes model wiped on every rack save, archive denied for non-admins, item edits taking the rack from the form instead of the item, no bounds check on positions, orphaned rack items on asset delete/transfer and orphaned racks on client delete. DB 2.8.0
2026-10-14 15:14:11 -04:00
Wrongecho
5013da98d6
API - Add software archive and unarchive endpoints
2026-09-22 09:04:08 +00:00
Wrongecho
e76feaa5b9
API - Do not show archived software/licenses
2026-09-22 08:42:48 +00:00
Wrongecho
9685ff0435
API - Add network create, update and archive endpoints
2026-09-14 10:19:04 +00:00
Wrongecho
f558414346
API - Domains add update endpoint
2026-09-10 15:52:53 +00:00
Wrongecho
a43a01f0f9
API - Add domains create, update, archive and unarchive
2026-09-10 15:16:36 +00:00
Wrongecho
dd2ee5c93f
API - Add Vendor create, update, archive endpoints
2026-09-10 14:19:00 +00:00
Wrongecho
4bd503d8cb
API - Only show non-archived vendors
2026-09-10 14:04:53 +00:00
Wrongecho
cc909b67ae
API - Documents read should only show unarchived docs
2026-09-08 10:50:53 +00:00
Wrongecho
f4936d640c
API - Add document archive and unarchive
2026-09-08 10:04:50 +00:00
Wrongecho
7898c16848
API - Location read should not show archived locations
2026-09-07 13:53:47 +00:00
Wrongecho
79262f26b4
API - Add location update, archive and delete
2026-09-07 13:46:15 +00:00
Wrongecho
8c9e049d7e
Tickets API - Add update endpoint
2026-09-04 13:36:03 +00:00
Wrongecho
5785d3cd05
Credentials API - Add archive, unarchive and delete endpoints
2026-09-04 13:03:34 +00:00
johnnyq
3acb1ad754
Fix ticket creation emails always saying Open, API tickets staying New when assigned, and the bulk assignee list filter
2026-09-03 17:18:32 -04:00
Wrongecho
70216f97b9
Contacts API - Contact must be archived before deletion
2026-09-02 07:45:39 +00:00
Wrongecho
d16ae9bc49
Client API - Add delete endpoint (thank you @BoredManCodes)
2026-09-01 15:09:59 +00:00
Wrongecho
7b986ed196
Bugfix: Client update API would error out if client_lead/client_is_lead was not specified
2026-09-01 14:47:44 +00:00
Wrongecho
450f2492ea
Tickets API - add close endpoint (simplify)
2026-09-01 13:18:30 +00:00
Wrongecho
e95b3c1977
API - Add app logging when auth is fine but queries fail
2026-09-01 13:18:02 +00:00
Wrongecho
7fe0f8638c
Tickets API - add close endpoint
2026-09-01 13:13:10 +00:00
johnnyq
36ea4a9a80
API: allow reads to filter by client_id on top of RBAC client scoping
...
The RBAC rework dropped the client_id read filter along with per-key client scope, so an all-clients key could no longer narrow to one client. apiClientScopeSql() now appends the filter after the scope fragment, so it can only narrow, never widen. Reads only - writes take client_id as their target client.
2026-08-31 18:30:09 -04:00
wrongecho
7442e0c2c8
Move interface deletion inside delete check otherwise the count is of the interfaces not the asset
2026-08-31 21:42:07 +01:00
johnnyq
68f18064c6
Fix Syntax error in name, update contributing
2026-08-31 16:27:30 -04:00
johnnyq
4e1d72e06d
Roll SLA email targets up to business days, escape priority, validate priority in the tickets API
2026-08-27 15:15:40 -04:00
johnnyq
bf04d6a757
Ticket default to Medium Priority unless specified, as this is just good practice
2026-08-27 13:04:19 -04:00
johnnyq
a96324628a
Fix broken cron page due to the select * sweep, note thi sdid not break cron itself
2026-08-09 13:27:51 -04:00
johnnyq
d484629ebc
do not update ticket status in history if it is the same
2026-08-08 12:41:34 -04:00
johnnyq
b3744e9ed5
More sweeps to replace select * with actual returned column names dramatically reduces php memory usage and speeds up processing dramatically especially in the crons since they run all the time
2026-08-06 13:10:23 -04:00
johnnyq
b8c9d5b4cf
Query Optimization: Select only needed columns instead of SELECT * on looped queries
2026-08-06 12:59:43 -04:00
johnnyq
83383599a1
Add clientScopeSql helper for client-scoped list queries
2026-08-06 11:25:11 -04:00
johnnyq
49a3c2d266
Enforce client scoping on API expense reads and record updates
...
Fixes (expenses/read.php missing apiClientScopeSql), plus an unscoped UPDATE in contacts/update.php and follow-up writes firing on zero-row updates in assets/credentials.
2026-08-06 11:00:49 -04:00
wrongecho
d74c9743be
Feature: Add invoice_items API endpoint (adding line items to an invoice)
2026-08-03 20:53:53 +01:00
johnnyq
ad15fabbb3
Credential length guard
2026-08-02 16:30:14 -04:00
johnnyq
23a09f54fc
Reworked getFieldById to remove escaping and and reworked everything that uses the function to also escape, was causing double escaping in many places this standardizes the function
2026-08-01 15:33:48 -04:00
johnnyq
75028ba09a
Fix some Ticket History gaps
2026-08-01 14:33:37 -04:00
johnnyq
162a597da9
Add SLA pausing, SLA reports, SLA filtering and kanban SLA state (phase 3)
...
Statuses can be flagged to pause the resolution clock; sla_history records the intervals a ticket's clock actually ran and the deadline is re-based on remaining budget when it resumes. Adds SLA Summary and SLA by Client reports, an SLA state filter on the ticket list, SLA colouring on kanban cards, and an Urgent column on the Tickets by Client report. DB update 2.5.1. Also fixes resolution SLA verdicts being skipped when resolving via kanban or the client portal.
2026-07-29 13:02:27 -04:00
johnnyq
e76b384606
Add ticket reply API endpoints
...
GET /api/v1/ticket_replies/read.php and POST create.php, so an RMM or
monitoring system can append to a ticket it did not open.
Replies default to Internal so an integration cannot email a client by
omitting a parameter. Public replies mark first response, notify the
contact and watchers, and fire the same custom actions as the agent
reply handler. An optional ticket_status also sets the status, and
resolves the ticket and marks the resolution SLA when set to 4.
Replies are always joined to tickets so ticket_client_id is checked
against the key user's client scope, and the client_id named on a write
must match the ticket's own client. The reply is attributed to the user
the API key runs as.
read.php resolves ticket_reply_by_name, since that column holds a
user_id on Internal and Public replies but a contact_id on Client ones.
2026-07-29 01:53:18 -04:00
johnnyq
d08ef6184a
Add optional ticket SLAs
...
Response/resolution targets stamped at creation from per-client/priority assignments, business-hours due date math, warn/breach alert stages via cron/ticket_sla.php, ticket list coloring, per-ticket SLA override, admin page for plans/assignments/business hours. DB update 2.5.0. No behavior change unless SLAs are assigned. Bulk reply now only counts Public replies as first response.
2026-07-29 00:00:42 -04:00
johnnyq
04bf3c234f
Read API credential decrypt password from body instead of query string
...
Keeps the credential decryption secret out of the URL, so it no longer lands in web-server access logs, proxy logs, or browser history. credentials/read.php now reads api_key_decrypt_password from the request body, matching create/update. Consumers reading decrypted credentials must send it in the body, not the query string.
2026-07-25 17:08:22 -04:00