Skip to content
faceela

Odoo for a UAE Trading Company: What Ships, What You Configure, What You Build

· 14 min read · Faceela

"Does Odoo do landed cost?"

It is the first question a trading company asks, and the answer is yes, which is why it is a poor question. Odoo ships landed costs. It ships consignment, a dropship route, multi-currency with an automatic exchange difference posting, and unit conversion between the carton you buy and the piece you count. On a feature list, a UAE trading business is very well served.

The second question decides the project, and almost nobody asks it: when all of that has been switched on, does the shipment still exist as a thing that earned or lost money, after the goods have been split across four invoices, half of them sold before the clearing agent's bill arrived and some of them moved to your other entity? That is not answered by a feature. It is answered by configuration decisions, two or three reports somebody has to specify, and at least one rule no software will enforce for you.

The product-neutral version of the argument — what any system has to model for a trading business, whoever makes it — is the margin is in the shipment, not the invoice. This is the Odoo companion: what the product genuinely ships, what has to be configured, what has to be built, and which trading companies should not buy it at all.

We are an accredited Odoo partner, and we moved a general trading company off Zoho Books and Zoho CRM onto Odoo in 2023. Read the section arguing against us with that in view, and read it anyway.

Landed cost: the feature is real, the discipline is not in the box

Start here, because for a trader this is the whole argument.

Landed costs are switched on in the Inventory app's settings, under the Valuation section. A landed cost is then a document you apply to one or more receipts, carrying cost lines — freight, insurance, duty, clearance — each with a split method that decides how that line is spread across the goods. The split methods are Equal, By Quantity, By Current Cost, By Weight and By Volume. And the products must be costed for it: they have to sit in a product category whose costing method is Average Cost or FIFO. A standard-price category cannot take a landed cost at all.

Take that list seriously, because it is better than it looks. Freight quoted per cubic metre allocates by volume; per kilogram, by weight; insurance follows value, which is By Current Cost; per-container handling allocates Equal. Those are the bases a trading business actually uses, and they are selectable per cost line rather than per document.

Now the gap, which you will meet in your first month: none of the five is duty.

Duty is assessed per tariff line at rates that differ by line, and no split method reads a tariff classification off the product, because Odoo does not hold a tariff rate as a costing input. So a mixed container carrying three duty treatments is either three landed cost documents split by value within each group, or one document whose valuation adjustment lines are edited by hand. Both work; neither is automatic; and whichever you pick is a process a clerk will perform two hundred times a year. Make the vendor build it in front of you, and count the clicks, because the clicks are the cost.

The larger point is not a limitation of Odoo but a category error people make about software generally. The estimate-then-true-up pattern a trading business needs — value the goods at receipt using standard rates per route, then post the differences as the real invoices arrive — is not a feature. It is a way of working the product permits and does not supply.

Odoo will let you post a landed cost against a receipt from two years ago. Nothing in the product will tell you the shipment is closed.

So the cost-complete rule — a shipment is final after a stated period, and further cost is a period expense — has to be written by you, owned by a named person, and reported on. Without it, no shipment margin is ever settled, and the report that says last quarter earned what it earned will quietly change next month.

The carton, the piece, and the ratio nobody checked

In an accounting package, "CTN" is text that prints on an invoice. In Odoo it is arithmetic, and it runs on every receipt, every pick, every valuation entry and every margin line.

The mechanics are strict, and the strictness is the good news. Every unit of measure belongs to a category; each category has a reference unit; Odoo converts between two units only when both are in the same category; and a purchase unit of measure must therefore be in the same category as the product's own unit. A unit larger than the reference carries a ratio — a box of six is 6.00000 — and that number is now load-bearing in the ledger.

Consider a purchase of 100 cartons at AED 120 a carton. If the item's ratio says twelve pieces and the carton in the warehouse holds ten, Odoo receives 1,200 pieces at AED 10 each. The truth is 1,000 pieces at AED 12. The total value is right, which is exactly why nobody catches it: the trial balance agrees, the vendor bill matches, the accountant is satisfied. Meanwhile stock is overstated by 200 pieces that do not exist and the sales team is quoting off a unit cost a sixth below the real one, on every deal, until somebody counts.

Two disciplines prevent it, and neither is technical. The first is that every item's ratio is confirmed against a physical carton by somebody in the warehouse, not against the supplier's catalogue by somebody in the office — pack sizes change without notice and catalogues lag. The second is that "box" is retired as a word. A unit of measure in Odoo is a global record shared by every product that uses it, so one carton unit cannot mean ten pieces for one item and twenty-four for another. Where pack sizes vary by product, that is what Odoo's product packagings are for, and which mechanism each item needs is a question to settle before the item master is loaded rather than after.

Buying in euro, selling in dirhams

The dirham's peg to the dollar removes exposure on dollar purchases and removes it on nothing else. Every euro, yen, sterling, renminbi and rupee purchase carries a real position, opened when the price is committed and closed when the payment is made.

Odoo handles the accounting properly and without being asked. Transactions are recorded in their original currency; exchange differences arising on settlement post automatically to dedicated gain and loss accounts through a dedicated Exchange Difference journal, configured once in the accounting settings; and there is a standard Unrealized Currency Gains and Losses report for open positions on the balance sheet. As accounting, that is complete. As management information it is not, and the gap is invisible from a demo.

An exchange loss in the Exchange Difference journal is a finance line, not a cost of the shipment that caused it. So the container bought in euro against a rate assumed in March, sold in June at a price set on that assumption and paid for in August at a different rate, reads as a good deal on your shipment margin report while the loss sits elsewhere, aggregated with every other currency movement in the business. Correct accounting, misleading commercial picture, both at once.

Attributing the movement to the deal is a deliberate design decision, not a checkbox. And the report that changes behaviour is the one Odoo will not produce until somebody specifies it: open commitments by currency, with the rate assumed when the goods were priced, while the position is still open.

Stock you hold and do not own

Consignment is two problems sharing a name, and Odoo covers one of them cleanly and leaves the other to configuration.

Supplier stock in your racks. The covered case. Consignment is enabled in the Inventory settings under Traceability; a receipt then carries an Owner, meaning the vendor who supplied the goods; and Odoo's documentation is explicit that because the consignee does not own them, consignment stock does not appear in the stock valuation report and has no effect on the consignee's inventory valuation. Custody without ownership, modelled correctly, out of the box.

Your stock at their site. The owner field does not solve this direction, because the goods are yours. What you need is a location representing that customer or agent, a movement that puts the goods there without invoicing them, valuation that continues to include them, and an ageing report over that location — because the risk with consignment stock you own is not theft, it is time. Fourteen months at a customer who has stopped reordering is an unrecognised write-off nobody is looking at.

That is configuration rather than code — locations, a route, a report — and exactly the sort of thing left out of a scope written from a feature list. Consignment at a hospital is the ordinary commercial model in parts of medical device distribution, where stock sits in a theatre cupboard for months and is invoiced only on use, and there the ageing report is how you find the expiring boxes.

Underneath both directions is one fact: custody and ownership are separate attributes of the same goods, and a system that conflates them is wrong in one direction or the other — which is one of the reasons your stock figure is wrong before you change any software at all.

The deal that never touches your warehouse

Back-to-back trading is where Odoo is at its best, and it is worth saying so plainly in an article that spends most of its length on caveats.

Dropshipping is enabled in the Purchase app settings under Logistics, then set as a route on the products that use it. From there the chain holds itself together: a sales order for a dropshipped product generates a request for quotation automatically; confirming that becomes a purchase order; and a dropship receipt is created and linked to it, with the vendor as the source location and the customer as the destination. The goods never enter a warehouse and the system never pretends they did.

That linkage is the valuable part. The generic advice is that the purchase order should be linked to the sales order at creation rather than matched afterwards by a person with a spreadsheet, because manual matching works until volume rises and then stops working without anybody noticing for a quarter. Odoo does it as standard, and for a trading company doing much of its business back-to-back, that alone is a large part of the case.

Two things the route does not settle. The Incoterm decides when ownership passes and therefore when the goods are on your balance sheet, and it belongs on the transaction rather than in a trade file in somebody's drawer. And the customer takes delivery before the supplier's invoice arrives, so the sale posts with no cost against it unless something raises the accrual. Odoo's bill control policy is the lever — a purchase order bills either on ordered quantities or on received quantities, and three-way matching works only with the received-quantities setting. Received is the correct choice for a trader, because it ties the bill to the goods rather than to the order. Have it demonstrated on a dropship specifically, where "received" means a receipt validated at a customer's address rather than into your own warehouse.

Credit limits, and what a warning is actually worth

Credit control is where a trading business most often discovers that its system is not a system.

Odoo carries a credit limit against the customer. What we will not state as a fact — because we could not establish it from Odoo's published documentation, and because it has moved between versions — is precisely which documents refuse to confirm when the limit is crossed, and who may override the refusal. So put it in the demo, in these words: show me a salesperson trying to confirm an order for a customer over his limit, and tell me whether he can complete it. Odoo's documentation for the point-of-sale customer account is explicit that the credit warning there does not prevent a sale from proceeding — a useful reminder that "the system has credit limits" and "the system stops the order" are different sentences.

The argument beneath the question needs no product facts. A credit limit is a control only if the block is real, the exception has a named owner, and the exception expires. A warning a salesperson clicks past is a log entry; a block the owner releases by telephone is the same phone call you had before, with a licence fee attached. What a system genuinely changes is that the release becomes a record — who released it, for how much, and whether the customer then paid — so that at quarter end you can read the exceptions and see that four were the same customer.

Where Odoo needs real work for a trader

Honest list, in the order we usually meet them.

Supplier rebates. For a distributor with a principal, rebates are frequently not a rounding item on the margin — they are the margin. We know of nothing in standard Odoo that accrues a tiered rebate at the point of sale and shows the running position against the target with six weeks of the period left. That is a build, scoped and priced as one, and if a vendor says otherwise, make them show it rather than describe it.

Demurrage attribution. Odoo will take the shipping line's invoice as a landed cost line perfectly well. What it will not tell you is why the container sat — a late document, an unchased approval, an unbooked inspection. That reason is a field somebody adds and a person fills in, and it is the difference between a report about your clearing process and a number that reads as weather.

The shipment as a surviving object. Odoo's landed cost attaches to a receipt. Whether the shipment's identity survives the goods being split, partly returned, transferred to your second entity and sold across three months is the one thing to test with your own data.

The two reports. Cost-complete status of every open shipment, and open exposure by currency. Neither is exotic; neither exists until it is asked for.

Each of those is configuration, a report, or code, and the difference has a long commercial tail. A report is cheap and safe. A field is cheap and safe. A new posting behaviour is code, and code is owned forever — the boundary set out in configuration against customisation.

And one thing on this list is not a feature question at all: whether stock sits in a designated zone, whether a movement to the mainland is an import, and which entity owns the goods at each point are settled by your entity and location structure, designed long before anybody configures a tax code. The free zone against mainland trade-offs deserve the argument before that structure is built.

When Odoo is the wrong buy for a trading company

There are trading businesses for which everything above is over-specified, and we have told companies so.

When your shape is headcount, not process. Odoo Enterprise charges per user. A trading company is very often twenty-five people of whom eighteen are in a warehouse and a showroom, running one entity, one currency, one warehouse and a clean order-to-invoice flow. That company is paying per head for governance it does not need. The full pricing argument, including the products that charge per organisation or per installation instead, is Odoo against Zoho and Tally — and for a good number of readers it ends the conversation, correctly.

When your landed cost problem is ten rows. If you import in dollars, from two suppliers, on one route, with a single duty treatment, your landed cost model is a spreadsheet and it is right — right because the person who maintains it understands it, and because maintaining it costs an hour a month. Replacing that with a configured module is not an improvement; it is a transfer of the hour to a licence and an implementation fee.

When the missing thing is a rule, not a system. If shipment margins are unreliable because nobody ever declares a shipment closed, Odoo gives you the same problem with an audit trail and a subscription. Write the rule first. If it holds for a quarter in a spreadsheet, buy the system that scales it. If it does not, it will not hold in software either, and the implementation will be blamed for something it never caused.

The afternoon that settles it

Do not accept a demonstration on the vendor's data. Take your own item list and one real shipment, and ask for a single afternoon.

Receive a mixed container of three products at three tariff rates and different weights; allocate freight by weight, insurance by value, and duty per line; then count the manual steps. Sell most of it, post the clearing agent's invoice and a demurrage invoice afterwards, and show where the cost lands for the goods already gone and the goods still on the shelf. Put one line through the dropship route. Receive supplier-owned stock and confirm it is absent from the valuation report. Settle a euro payable at a different rate and show which journal took the difference. Then try to confirm an order for a customer over his credit limit, using a salesperson's login rather than an administrator's.

If all of that works in one afternoon, the product fits your business. Everything that needed a spreadsheet or a consultant's promise is your scope, found before signature rather than in month seven.

Where this leaves you

Odoo is a good fit for a UAE trading and distribution business, for specific reasons rather than general ones: the split methods map onto real allocation bases, consignment is modelled as ownership rather than as a note, the dropship chain is held by the system, and the accounting for currency happens without being asked.

What it does not supply is the part that was always going to be yours. Which ratio a carton has. When a shipment is closed. Whether the block on a credit limit is real. Whether the person who decides those things has been named. Settle those four before configuration begins and you get a system that tells you what you earned; leave them to be discovered during the build and you get a very capable product producing a margin figure your own directors do not trust.

If you want those decisions identified, argued and written down before anybody quotes a configuration — including the parts of the answer that say a spreadsheet and a controller would serve you better — that is where an Odoo implementation starts.

Source note

The Odoo capabilities described above were checked against Odoo's own published 19.0 documentation on 26 August 2026: the landed costs page in Inventory valuation, for enabling the feature, the split methods (Equal, By Quantity, By Current Cost, By Weight, By Volume) and the requirement that products sit in an Average Cost or FIFO product category; the units of measure page in Inventory product management, for categories, reference units, the same-category conversion rule and purchase units of measure; the consignment page in Inventory daily operations, for the Traceability setting, the Owner field, and the statement that consignment stock does not appear in the stock valuation report; the dropshipping page in Inventory daily operations, for the Logistics setting, the product route, and the sales-order-to-purchase-order-to-dropship-receipt chain; the bill control policies page in Purchase, for the ordered-versus-received quantities policy and the statement that three-way matching works only with received quantities; the multi-currency page in Accounting, for the Exchange Difference journal, its gain and loss accounts, and the Unrealized Currency Gains and Losses report; and the point-of-sale customer account page, for the statement that the credit warning there does not prevent a sale from proceeding. Odoo changes behaviour between versions and between editions; confirm the current position on the version you are buying before you rely on any of it.

Next step

Is this happening in your company?

If the article described your situation, the useful next move is a diagnosis rather than another article. Tell us the one thing that is not working.

Monday to Friday, 9:00 AM – 6:00 PM (GST)

Prefer we call you?

Leave your WhatsApp number and we will reach out.

We reply on WhatsApp first. Include your country code.

No newsletter, no reselling your number. We use it to reply to you — see our privacy policy.

WhatsApp us