Last week I chatted with a finance director, and he told me something quite typical. On the second day of the month-end closing, the boss asked, "How did last month's revenue drop by six points?" He had the newly deployed AI assistant look into it directly. In a few seconds, the system gave a number and added an explanation: mainly due to delayed orders from two major clients in East China. It sounded quite plausible.
He asked one more question: Is this "revenue" calculated based on invoicing or based on revenue recognition? The assistant couldn't answer. He went back to check himself and found that the portion that had been invoiced but not yet shipped had been included—this batch of goods was sitting in the warehouse, the customer had not yet signed for it, and under the contract revenue would not be recognized until next month.
This is what we’re talking about today. On November 13, Databricks launched the Genie ChatGPT plugin, allowing employees to directly ask questions about data in SAP ERP using natural language. The technical pipeline is quite thoughtfully built, but what really determines whether this system can be used is not the pipeline—it’s what the word “revenue” actually refers to.
1. A Business Deal Has Four Dates in the System
There is a sentence in that Databricks explanation that I think is the most valuable part of the entire piece: a sales order, a shipment, an invoice, and a revenue posting can be different stages of the same transaction, and may also fall in different accounting periods. So when someone asks 'Why did revenue drop?', the answer depends on whether you are using recognized revenue, invoiced sales, or confirmed orders, and also on how the books, currency, returns, and intercompany transactions are handled.
In Odoo terms, a transaction leaves at least four dates in the database:
| Business event | Which object does it fall on | Date field |
|---|---|---|
| Customer places an order | sale.order (Sales Order) | date_order Order Date |
| Warehouse shipping | stock.picking (Transfer Order) | date_done Completion date |
| Invoice | account.move (Customer Invoice) | invoice_date Invoice Date |
| Bookkeeping and Revenue Recognition | The posting date of account.move, or the revenue recognition entry | date accounting date |
When you say “last month’s revenue,” which field you use can make the answer differ by a month. All four approaches are plausible, but only one is the one both you and your boss recognize. The other three aren’t wrong; they just haven’t been clearly specified.
The pitfalls on the purchasing side are more nuanced. A purchase order can have multiple scheduled lines, each with its own delivery date and quantity (date_planned on purchase.order.line). Inventory numbers also include items in quality inspection and those reserved by other orders—once reserved_quantity on stock.quant in Odoo is deducted, the available free_qty is not the same number as qty_available. On a partially received order, the header says delivered, but the shortage is still there.
The easiest line in a report to gloss over: “The report ran, and the data is fine.” Running it only proves the SQL syntax is correct; it doesn’t prove it answers the question you asked. In a demo, these two things look exactly the same.
II. If definitions are not written down, the model can only guess
Genie's approach is worth a look. It relies on two things to understand questions: Genie Ontology, and the technical metadata provided on the SAP side.
Part of the Ontology consists of definitions explicitly modeled in Unity Catalog—for example, an approved revenue metric specifies which ledger, which accounting calendar, and what rules to use for currency conversion. Another part is context learned from dashboards and saved queries. SAP Business Data Cloud can also provide field descriptions and primary/foreign key relationships, which help it join tables correctly.
But one thing must be underlined: which transactions count toward this metric is defined by the business team. It's not inferred by the model, nor decided off the top of an implementation consultant's head.
When this saying is applied to a project, it becomes a card. I've pushed this thing in quite a few projects—at first everyone thought it was uncool, but later every time they relied on it to argue.
| Column | What should I write? | Common mistakes |
|---|---|---|
| Metric name | How do you say it colloquially, and how do you write it on a report? | One name corresponds to three reports |
| Data retrieval object | Main table + related tables, clearly specify the hierarchy | Calculate revenue using the orders table |
| Filter conditions | Status, Company, Customer Type, Return Processing | Factor in internal transactions |
| Date field | Which date exactly is it | Four dates used interchangeably |
| Amount basis | Tax-included / tax-excluded, currency conversion, discount | Functional currency and original currency are not distinguished. |
| Approver | Whoever signs, whoever makes changes reviews. | No one acknowledges it once it's written |
Six sections, one card, and ten high-frequency metrics means ten cards. It sounds like red tape, but it is the only thing that can produce evidence when three departments are arguing. More practically: this card is also a prerequisite for whether AI data querying can go into production. If you let the model guess the definition of “work in process,” it will give an answer that is grammatically perfect but has a questionable definition, and then it gets forwarded into management’s weekly report.
III. What can be asked and what can be changed are two authorization tables
There is another layer that is easy to overlook: this Databricks setup is read-only. Changing purchase orders, releasing frozen invoices, and making posting adjustments still require a separate authorized ERP interface or workflow. The report puts it bluntly—the plugin gives ChatGPT an interface for ERP analysis; it does not handle write operations.
This division is worth copying into your own architecture. Reading and writing are not the same permission level; they are two worlds.
- The boundary of reading is 'which rows can be seen'. Genie enforces permissions in Unity Catalog according to the logged-in user, not permissions carried by the plugin itself. In Odoo, the corresponding mechanism is ir.rule record rules plus company context; who can see which company's documents depends on this.
- The boundary of writing is “which actions can be triggered.” It is not about giving the model a database connection, but rather turning the permitted actions into a limited set of tools or server actions; the model can only request dishes that are on the menu.
- There is another layer: 'where the results will appear.' Zero-copy sharing only explains how the data is accessed; the answer will still be displayed in the dialog box. The purchase order number, quantity, and confirmed delivery date are what the purchaser needs; there is no reason for the supplier's bank account number to appear in this kind of analysis. This is the problem that a field-level visibility list needs to solve.
One more reminder about the sense of time. Zero-copy does not mean the answer is fresh. The timeliness of the answer depends on when ERP changes enter that data product, and when the other datasets in the query were last refreshed. A buyer may be looking at open purchase orders and warehouse inventory at the same time, and the two datasets may refresh on different cadences. A large receipt arrives right after one dataset refreshes, and the conclusion changes. Therefore, the results must display data timestamps—this is not a nice-to-have; it lets people know which moment's books they are looking at.
Multi-company, multi-currency is another high-frequency failure point, and it's harder to prove than single-company. The same "group revenue" can go wrong in three places:
- Scope. Is it the current company (env.company) or the set of active companies (company_ids)? In Odoo these are not the same thing; switching the company in the interface changes the numbers, but the report title often does not follow.
- Currency. Should you use the document's original currency, the company's functional currency, or the group reporting currency? If conversion is used, which day's exchange rate should be applied—the document date, the posting date, or the month-end rate? The exchange rates on these three dates may all be different.
- Intercompany transactions. Should intercompany sales and purchases be eliminated in group consolidation? If not eliminated, revenue will be inflated; if eliminated, you then have to explain why the individual company's financial statements don't reconcile.
If these three points aren't clearly written down, cross-company data querying is basically unusable. And they happen to be the parts that no one is most willing to put into documentation, because writing them down means you can't just change them casually later.
IV. Use old reports as the exam paper; don't use new reports as the grade
Databricks provided a very practical pilot approach, and I think it can be adopted directly. Take an existing purchase order exception report as a baseline, have Genie run it with the same cutoff time and the same plant scope, and then compare line by line.
The key lies in what the test set must include: partially received orders, cancelled planned lines, revised supplier confirmations, and users with permissions for different plants. These categories happen to be the easiest to answer incorrectly. Check three things—whether the answer uses approved definitions, whether it links back to specific records, and whether it displays the data timestamp.
Don't overcomplicate the metrics either: missed material shortages, false alarms, and the time spent investigating an issue. Three numbers are enough.
This approach has an advantage: it doesn't compare who answers faster, only who answers correctly. And "correct" has a reference point—last month's report is that reference point.
By the way, a word about scale. SAF-Holland used SAP Business Data Cloud plus SAP Databricks to analyze more than 100 million SAP records, including scheduling agreements, deliveries, customers, and materials, while S/4HANA remains its system of record. David Gund, their senior manager of global digital intelligence, estimates that a similar analytics workflow would take at least five times as long elsewhere. The lesson from this case is not that the cloud is five times faster, but that the data layer can be built separately while the system of record cannot be moved. Once who keeps the books and who produces the data are separated, many debates become clear.
V. Three Sentences for Those Who Are Doing This
Start by writing definition cards for ten high-frequency metrics — whoever signs off is accountable.You don't have to wait for an AI project to be approved; this alone can cut report disputes in half.
Authorize separately what can be asked and what can be changed.Run a read-only connection for three months first, to see clearly what people will ask and what kinds of questions come up, then discuss whether to let it touch the data.
Use old reports as a baseline and compare line by line. Do not use a newly built dashboard to prove another newly built dashboard right. The older the reference point, the more credible it is.
Back to that CFO. What he did later was simple: break "revenue" into three terms—invoiced, shipped but not invoiced, and recognized revenue—each term paired with a card that clearly states the data source and the approver. Then require the assistant, when answering, to first state which one it is using.
The system didn't change, the model didn't change—just one extra piece of paper. But since then, no one at the monthly closing meeting has argued for half an hour over "which revenue do you mean when you say revenue".
When it comes to querying data, the most expensive part has never been compute.
Reference source: ERP News, "How Databricks Genie Brings SAP ERP Data Into ChatGPT" (2026-11-13); Databricks release notes dated 2026-11-11 and Genie Ontology release information.
Zhongdi Information · Enterprise Management Digitalization Observations · Odoo field names in this article are based on Odoo 19/20.
