The most valuable thing a partner can say during an ERP project is no. Not out of laziness, and not to protect a fixed price, but because every custom module is a cost the client carries forever: through every upgrade, every new hire who has to learn it, and every audit that asks why the system does something the manual does not describe.
So the first question is never can we build it. It almost always can be built. The question is whether it should be.
Configure it when the difference is habit
A surprising amount of what looks like a hard requirement turns out to be the way one person has always done it, and nobody has ever been asked why. If standard Odoo does ninety per cent and the last ten is preference, the honest answer is to change the preference. That conversation is uncomfortable for about ten minutes and saves years of maintenance.
The same applies when an automation rule, a server action or a Studio field solves it. If a community module already does the job and is actively maintained, use it. If two departments do the same thing differently because nobody ever agreed a single process, the fix is agreement, not code.
Build it when the process is how you compete
There is a category of requirement where a custom module is obviously right. When the process is genuinely yours, the thing that makes you better than the company down the road, standardising it away would be destroying the value you are paying to protect.
It is also right when a regulator, a customer contract or a tax authority requires something specific, when the manual workaround costs more hours every month than the module costs once, and when another system has to exchange data with Odoo and neither of them speaks the other's language.
The test in one sentence
If the requirement would still exist at a well-run competitor doing the same work, it is probably configuration. If it exists because of something specific to this business, its customers or its regulator, it is probably a module.
What we do with the answer
Discovery produces a gap list before anyone gets a quote, and every gap on it is marked: fits, bends, or needs code. The client sees that list and can argue with it, which is the point. Nobody should discover in month four that a quarter of the budget went on modules that could have been a training session.
And when we do build, it goes in as a proper addon with tests and documentation, delivered as source that the client owns. Not because that is generous, but because the alternative is a system that cannot be upgraded, and we would rather earn the renewal than hold the door shut.