Skip to content

Developer notes

Overview · Installation · Configuration · Usage · FAQ

Every list, count, bulk scope and single-order check starts from what core fn_get_orders() builds for the current user (get_conditions): the company condition (vendor = own orders, Ultimate = selected storefront), the 4.21 storefront restrictions of administrators, hidden parent orders, and every condition that core and other add-ons add through the pre_get_orders / get_orders hooks. The desk filters are added on top. So the desk never shows or changes an order that the core orders list hides from the same user.

  • Paging and counting run on the server (COUNT(DISTINCT order_id) + LIMIT), sorted by indexed columns (timestamp, order_id, status, total).
  • The quick search uses the indexed order id; e-mail, name and phone use LIKE; the SKU search uses a sub-query on order_details.product_code (prefix match).
  • Row data (items, thumbnails, shipping and payment names, tags, note counts, customer order counts, countries) is loaded per page in one query per kind, never per row, and only for the visible columns.
  • Measured on Multi-Vendor 4.21.2 with 50,000 orders: see the FAQ.

The desk changes statuses only with core fn_change_order_status() and the core notification rules (fn_get_notification_rules()), exactly like the core orders list. Stock, invoices and credit memos, e-mails, the order history of other add-ons and their hooks behave as usual. If core or another add-on keeps the old status, the desk reports it.

Duplicate / reorder opens the core order editor (order_management.edit?order_id=N&copy=1). Invoices and packing slips use core fn_print_order_invoices() / fn_print_order_packing_slips().

Table Contents
?:kv_oap_tags tag_id, company_id (owner scope: 0 = store administration, vendor id on Multi-Vendor), name, color, position
?:kv_oap_order_tags order_id, tag_id (primary key both; index on tag_id)
?:kv_oap_events timeline: event_id, order_id, company_id (author scope), user_id, type (status, note, tag_add, tag_remove, email, print, export), data (JSON), created_at; index (order_id, event_id)
?:kv_oap_views saved views: user, scope, name, shared flag, params (JSON)
?:kv_oap_prefs per-user columns, sorting, page size
?:kv_oap_templates message templates per scope
?:kv_oap_jobs running bulk actions (spec, order ids, cursor, counters); rows older than 7 days are removed when a new job starts

Deleting an order (core fn_delete_order()) removes its tags and timeline entries (delete_order hook).

Hook Why
change_order_status_post Timeline entry for every status change (same arguments in 4.17.2 and 4.21.2)
delete_order Cleanup of tags and timeline entries
Template hook orders:tabs_extra + orders.post.php The Tags & timeline tab on the order page

The add-on prints nothing on the storefront and writes nothing on storefront GET requests (4.21 full page cache: nothing to do). The status hook also runs at checkout and in payment callbacks; it only inserts one row and never throws.

Endpoints (admin.php / vendor.php?dispatch=kv_order_admin_pro.<mode>)

Section titled “Endpoints (admin.php / vendor.php?dispatch=kv_order_admin_pro.<mode>)”
Mode Method Purpose
manage GET The desk page
rows GET JSON page of orders (filters, columns, sort, dir, page, per_page)
quick_view, timeline GET JSON with the drawer / timeline HTML
status, tags_set, note_add POST Single-order actions
tag_save, tag_delete, view_save, view_delete, prefs_save, template_save, template_delete POST Settings of the desk
bulk_preview, bulk_start, bulk_step POST Bulk actions (scope = ids or filters)
export, print, pick_list POST CSV download, invoices / packing slips, pick list

All POST requests use the core form protection (security_hash). Permission schema: view_orders; the controller checks change_order_status, update_order_details and exim_access per action, and the order scope for every order id.

License\Client::isActive() gates bulk_preview, bulk_start, export, print and pick_list. A started bulk job is always finished (bulk_step is not gated), so no half-applied action is left behind. The desk, quick view, single status changes, tags, notes and the timeline are never gated.

app/addons/kv_order_admin_pro/
addon.xml settings, tables, e-mail template
init.php, func.php hooks, settings info, licence helpers
controllers/backend/kv_order_admin_pro.php desk controller (admin + vendor panel)
controllers/backend/orders.post.php Tags & timeline tab on the order page
controllers/backend/kv_order_admin_pro_license.php "Check now" / cron licence check
schemas/menu/menu.post.php, menu_vendor.post.php Orders > Order desk
schemas/permissions/admin.post.php, vendor_multivendor.post.php
Tygh/Addons/KvOrderAdminPro/
Access.php privileges, scope, licence
Query.php core order conditions + desk filters, paging, scope ids
Rows.php batch loading of the row data
Tags.php, Timeline.php, Views.php, Prefs.php, Templates.php
Bulk.php preview, jobs, steps, status change
Export.php CSV
PickList.php aggregated SKUs
Ui.php desk configuration, statuses, formatting
License/ domain-bound licence client
Upgrade/ self-healing upgrade synchronizer
design/backend/templates/addons/kv_order_admin_pro/
views/kv_order_admin_pro/manage.tpl, quick_view.tpl, pick_list.tpl, components/timeline.tpl
hooks/orders/tabs_extra.post.tpl, hooks/index/styles.post.tpl, license/*
design/backend/css/addons/kv_order_admin_pro/styles.less, license.less
js/addons/kv_order_admin_pro/desk.js
var/langs/en/addons/kv_order_admin_pro.po