Skip to content
ERP & CRM 3 min read

Customize the 20%, and make it survive the next upgrade

Standard ERP covers the universal 80%. The last 20% is the part that's actually your business — and how you build it decides whether upgrades stay boring.

The webbox team ·

Every stalled ERP project we have been asked to rescue traces back to one of two mistakes. Either someone tried to make the company work the way the demo worked, or someone customized so aggressively that the system can no longer be upgraded. Both end in the same place: a team quietly running the business out of spreadsheets beside a system nobody trusts.

The 80/20

Out of the box, any credible ERP handles the universal 80%: sales orders, inventory moves, invoices, the chart of accounts, purchase approvals. Do not customize that part. It is the same in every company for a reason, and every line you change there is a line you will pay to re-test twice a year.

The other 20% is the reason you are competitive. It is the pricing rule nobody else has, the approval path your auditor insists on, the stock reservation policy that keeps your largest customer supplied, and the report your operations lead rebuilds by hand every Friday because the standard one does not quite fit.

That 20% is exactly what an extension is for.

What a safe extension looks like

The specifics differ by platform — AL extensions on Dynamics 365 Business Central, SuiteScript on NetSuite, Python modules on Odoo, DocTypes and server scripts on ERPNext — but the rules are the same everywhere:

  • It extends rather than modifies. Nothing in the vendor's own objects is edited in place.
  • Business logic lives in one layer and presentation in another, so a UI change never forces a logic change.
  • Permissions and record-level access are part of the module from the start, not a separate configuration exercise somebody forgets.
  • It is tested against the target version before anyone touches production, and re-tested against the next version before you upgrade.

Here is the shape of it on Odoo, as an example — inheriting the model rather than editing it, and calling through to the standard behaviour:

class SaleOrder(models.Model):
    _inherit = "sale.order"

    priority_tier = fields.Selection(
        [("std", "Standard"), ("exp", "Expedited")],
        default="std",
    )

    def action_confirm(self):
        # your rule, expressed once, in the framework's grain
        for order in self.filtered(lambda o: o.priority_tier == "exp"):
            order._reserve_priority_stock()
        return super().action_confirm()

The equivalent on Business Central is an event subscriber in an AL extension; on NetSuite it is a user event script. Different syntax, identical discipline: the vendor's code stays the vendor's, and the upgrade path stays open.

The test that tells you whether you got it right

Ask what happens at the next version upgrade. If the honest answer involves a developer manually reconciling your changes against the vendor's, the customization was built in the wrong place, and every future upgrade will carry that cost again.

If the answer is that the extensions are re-tested and the upgrade proceeds, then customization has done its job. Upgrades stop being something to dread, and your team stops doing by hand what the system should be doing for them.

That, in the end, is what an ERP is for. It is also why we write the extension rather than asking you to bend a working process to fit the software.

#erp#customization#upgrades#odoo#extensions
Share
T

The webbox team

Engineering

Notes from the engineers building software, ERP and AI at webbox.

Want help with something like this?

Tell us the problem. We'll come back with a plan, a price, and who'd actually build it.

  • Free scoping call
  • Reply within 1 business day
  • No lock-in