Developer notes
File map
Section titled “File map”app/addons/kv_sales_reports_pro/ addon.xml settings, tables, privileges, e-mail template init.php, func.php hook registration and handlers, settings variants controllers/backend/kv_sales_reports_pro.php reports, export, presets, digests, sync, rebuild, cron controllers/backend/kv_sales_reports_pro_license.php license "Check now" controllers/frontend/kv_sales_reports_pro.php view counter endpoint (POST hit) schemas/menu/menu.post.php, menu_vendor.post.php schemas/permissions/admin.post.php, vendor_multivendor.post.php, trusted_controllers.post.php schemas/full_page_cache/varnish.post.php own tables ignored as cache tags Tygh/Addons/KvSalesReportsPro/ Config.php settings, counted/refund/return statuses, RFM thresholds, licence state Sync.php report snapshot (full build, dirty queue, updated_at safety net, reconcile) Customers.php customer identity (user account or e-mail) Counter.php product views and cart adds per day Filter.php periods, comparison, buckets, SQL scope Report.php report queries View.php view data and formatting Chart.php inline SVG chart Digest.php, Presets.php, Csv.php, Money.php, Meta.php License/, Upgrade/ licence client, self-healing upgradesdesign/backend/templates/addons/kv_sales_reports_pro/ views, components, hooksdesign/backend/css/addons/kv_sales_reports_pro/styles.lessjs/addons/kv_sales_reports_pro/admin.js (admin) and func.js (storefront view counter)var/themes_repository/responsive/templates/addons/kv_sales_reports_pro/hooks/index/ view counter element + scriptReport snapshot
Section titled “Report snapshot”The reports never scan the core order tables. Sync writes one row per order (?:kv_srp_orders) and per order line (?:kv_srp_items):
- Full build (install, Rebuild): every order by
order_id, in batches of 500. - Dirty queue (
?:kv_srp_dirty):place_order,change_order_status_postand the RMA hookrma_update_details_postqueue the order; it is processed on the next run. - Safety net: orders whose
updated_atmoved past a watermark (kept 5 minutes behind the clock) are re-read, so direct database changes are picked up too. - Deletes:
delete_orderremoves the rows; a daily reconcile removes rows of orders deleted outside the hooks. - Runs: the cron dispatch, report page views (at most 1.5 s), “Update now” (AJAX steps).
Parent orders of Multi-Vendor checkouts and incomplete orders (N) are never stored; all other statuses are, and the counted statuses are applied when a report is read, so changing them needs no rebuild.
Per order: totals from ?:orders, taxes from order_data type T, items an RMA return took out of the order from type H (they are added back to gross sales and units), accepted returned items from ?:rma_returns / ?:rma_return_products. Item revenue = price x quantity x (1 - cart discount / line total), rounded so the lines add up exactly.
Measured on a test store with 200,000 orders (242,604 order rows including Multi-Vendor parents, 424,000 lines, 56,000 customers): full build 35 s with 50 MB peak memory; 500 changed orders 0.6 s; every report over 3 years under 2 s.
Tables
Section titled “Tables”| Table | Contents |
|---|---|
kv_srp_orders |
One row per order: checkout, company, storefront, customer, status, day, month, totals, gross, returned, refunded, units |
kv_srp_items |
One row per order line: product, checkout, company, storefront, status, day, units, revenue, returns |
kv_srp_customers |
Customer identity: u:<user_id> for accounts, e:<e-mail> for guests |
kv_srp_views |
Views and cart adds per day, product and storefront |
kv_srp_presets, kv_srp_digests |
Saved reports and e-mail digests |
kv_srp_dirty, kv_srp_meta |
Sync queue; watermarks and run marks (no ?:storage_data writes) |
All tables are InnoDB and removed on uninstall.
Hooks used
Section titled “Hooks used”Identical in 4.17.2 and 4.21.2: place_order, change_order_status_post, delete_order, post_add_to_cart (app/functions/fn.cart.php), dispatch_before_display (fn.control.php), rma_update_details_post (core RMA add-on). Storefront template hooks: index:scripts (post), index:footer (post).
Full page cache
Section titled “Full page cache”Product pages get a hidden element with the product id and the endpoint URL; it is the same for every visitor. The storefront script sends one navigator.sendBeacon POST per product and browser session (remembered in sessionStorage). The endpoint writes one counter row and nothing else; the table is listed in ignore_cache_tags, so no page is purged. Cart adds are counted in post_add_to_cart (a POST request).
Cron and console
Section titled “Cron and console”php admin.php --dispatch=kv_sales_reports_pro.cronRuns the sync (up to 10 minutes from the console, 50 s over HTTP) and sends due digests. Over HTTP it needs cron_password.
License check
Section titled “License check”The licence client (License\Client) verifies the key for the store’s domain once a day, only in the admin panel or from cron. Without a valid license: no snapshot sync, no view counter on product pages, no digests; reports and exports keep working with the data collected so far.