Settings¶
Profitability Copilot keeps its settings in OpenCart's own setting table, under the
module_profitability_copilot group. You set them at
Admin > Extensions > Extensions > Modules > Profitability Copilot.
Each key below carries where it applies. per store means a multi-store install can hold a different answer per storefront, and both are honoured: a read takes what that store holds, then what the default store holds, then the shipped default. install-wide means one thing serves every storefront, and the key's own description names that one thing.
Scope¶
| Key | Default | What it does |
|---|---|---|
module_profitability_copilot_statusper store |
0 |
Whether the extension is enabled. Set by the Status switch on this extension's own settings screen. While it is off nothing is recorded: an order that completes is not snapshotted, and the period it fell in stays empty for good, because the figures are frozen at the moment the order becomes real and are never recomputed from today's prices. Switching it back on does not backfill — Recalculate from a date does, deliberately and with a warning. |
module_profitability_copilot_api_enabledinstall-wide |
0 |
Whether the extension answers API requests at all. Off, every API route answers 404 api_disabled in the API's own JSON envelope, so an extension with its API off is shaped like one that has none. Read once for the whole installation from the default store rather than per store, because the credential it checks is OpenCart's own API user, which has no store of its own — and that is also why this is off until somebody decides otherwise: an OpenCart API credential cannot be scoped. It is not a user, so it carries no group, no store and no permission, and one of them opens every extension's API and core's own across every store. Switching this on therefore shows what the merchant pays their suppliers to every holder of a key to the installation, and the product form's cost permission does not reach it and cannot. |
Cost¶
| Key | Default | What it does |
|---|---|---|
module_profitability_copilot_default_cogs_marginper store |
empty | The gross margin to assume for a product with no cost of its own, as a percentage of the line's revenue. Empty means no assumption: such a line is recorded as unknown and excluded from both revenue and cost, and counted in the exclusion figure instead. Setting it changes nothing already recorded — every figure is frozen at the moment its order became real — so a store that sets it sees it apply to orders from that point on, and to anything a Recalculate touches. |
Which orders count¶
| Key | Default | What it does |
|---|---|---|
module_profitability_copilot_counted_order_statusesinstall-wide |
5,3,2 |
The order statuses whose orders count towards profit, as a comma-separated list of OpenCart status ids. Defaults to Complete, Shipped and Processing. The test is live: an order that leaves the set stops counting on the next page load with nothing of ours written, which is what makes a refund show up without a hook. |
module_profitability_copilot_counted_return_statusesinstall-wide |
3 |
The return statuses whose returns are taken off the figures, as a comma-separated list of OpenCart return status ids. Defaults to Complete alone. Returns are read live rather than stored, so editing a return's status corrects the figures with nothing of ours re-run. |
module_profitability_copilot_resellable_reasonsinstall-wide |
{"1":false,"2":true,"3":true,"4":false,"5":true} |
Which return reasons bring back stock that can be sold again, as a JSON object keyed by OpenCart reason id. A resellable return takes its frozen cost back off the cost side as well as its revenue off the revenue side; one that is not resellable loses the revenue and keeps the cost, which is what a write-off is and what a merchant is looking at when a product's margin is fine and its profit is not. Seeded from core's five reasons with Dead On Arrival and Faulty marked not resellable, and Received Wrong Item, Order Error and Other marked resellable. A reason the object does not mention is resellable, so a reason the merchant adds themselves restocks until they say otherwise. |
Fees and fulfilment¶
| Key | Default | What it does |
|---|---|---|
module_profitability_copilot_payment_fee_rulesinstall-wide |
{} |
What each payment method costs, as a JSON object keyed by the payment_method.code on the order — a percentage and a fixed amount per order. Calculated on the gross amount the customer paid, inclusive of tax and shipping, because that is what a gateway charges on; every other figure in this extension is ex-tax. A method with no rule costs zero and the order still counts, with the gap named on the Not-configured panel: an unconfigured fee understates cost by two or three percent, where excluding the order would throw away a nearly-correct figure to avoid a nearly-negligible error. |
module_profitability_copilot_fulfilment_rulesinstall-wide |
{} |
What each shipping method costs to fulfil, as a JSON object keyed by the shipping method code — a flat amount per order, or a percentage of the shipping charged. One term covers carriage and pick-and-pack, because a pick-and-pack cost is arithmetically the flat-per-order rule the carriage cost already is, and two settings with identical arithmetic is two places to enter half the number. A method with no rule costs zero, which is wrong under free shipping too — no default is right, and zero is the one that says so on the screen. There is no weight rule: oc_order_product does not record the weight the order shipped at, so one would price today's product weight against a year-old order. |
Advanced¶
| Key | Default | What it does |
|---|---|---|
module_profitability_copilot_diary_verbose_untilinstall-wide |
0 |
When detailed logging stops, as a unix timestamp, and 0 is off. Turning Detailed logging on from this extension's settings form stores the moment two days from now; the writer compares that against the clock every time it is asked for a DEBUG line, so the window closes on its own with no scheduled task and nothing to clean up. While it is open this extension records what it did in far more detail, and the shared diary consequently holds less history. |
What you cannot change, and why¶
These are fixed on purpose. Each one is a decision with a reason beside it rather than a setting nobody got round to adding.
Arithmetic¶
Money is stored and computed to four decimal places and displayed to two, everywhere, and neither number is settable. Four matches core's own money columns and the API convention's precision, so a figure crossing between them is never re-rounded; two is what a merchant reads. Totals are summed from the rounded components, so a breakdown never prints a cent off its own total — which is the failure a configurable precision reintroduces on whichever screen was written first.
An order-level discount is allocated across the lines in proportion to what each line is worth, and the rounding remainder goes to the last line in ascending order line id. Deterministic, one sentence to explain, and at most a hundredth of a cent per line — invisible at the two places a merchant reads. The alternatives all share one property: the same order, re-reported, allocates differently.
Every figure is ex-tax, except the payment fee, which is calculated on the gross the customer paid. That is not an inconsistency: the ex-tax rule governs revenue, because tax is money the merchant collects and hands on, and a gateway fee is a cost, charged on the gross the gateway actually moved. Making either side settable would let a store compute a fee its gateway does not charge, and reconcile against nothing.
The feed¶
The feed shows at most five insights, and each rule has a floor below which it says nothing at all — a minimum number of orders, a minimum amount of money, a minimum share of the period. None of the five rules and none of their floors is settable. A feed a merchant can tune is a feed that tells them what they already believe, and a cap they can raise is a dashboard that becomes a report nobody reads to the bottom of.
Cost¶
A line recorded as backfilled — priced from a cost that was not known when the order was placed — never goes back to reading as actual, whatever runs over it afterwards. The basis is a statement about how much to trust the figure, and a rerun that quietly upgraded it would erase the one signal saying this period was reconstructed rather than recorded.
A price at or below the recorded cost is shown in red on the product form and saved as typed. Clearance lines and loss-leaders are real decisions, and refusing a save on OpenCart's own form would be this extension overruling the store's owner on a figure that is theirs to set.