Guidance to work with Forks on Github for ERPNext only

friends, we need to manage a fork as code needs to be customised and it’s very essential to pull in new development from Frappe and ERP.

Few guidance note from experts will help a lot.

Thanks in advance !

https://alainber.medium.com/managing-forks-8213714e3076 This link may help, pls direct me to more pointers.

1 Like

The write-up is for those who expect to merge their changes to the main code of ERPNext. For example, if you are forking ERPNext to code a fix which you plan to request the Frappe team to admit to the main code if they approve, you do this.

However, if you are look at developing code to put in your own functionality, you have to create your new-app and do install-app into your site. For example, I do not like the way Account doctype does magic sauce with the Account autoname, and I want to use Account Number as the Name and Account Name will have no changes, this way, I can use Account Number as Parent Account Name (hehehe). What I do is install a new-app, and put the monkey patch code to redefine the Account def methods, and all the other stuff related to this functionality. (For another functionality, I put in another new-app and install-app. I try not to mix different functionalities in a single app).

Thanks, Yes , My requirement is reverse and you understand well. please help me to how to manages major changes that require py files and keep fetching new developments in our fork repository from ERP / Frappe branches that are generally client specific

If your changes involve adding functionality to the ERPNext code, then you manage this with hooks and fixtures into your new app. (There are lots of discussions here about fixtures). This means, that all the def methods of the classes of ERPNext still execute and you are not overriding any of the class methods.

But if you are replacing the def method of the ERPNext class because you do not like how it works and you are replacing it with your own functionality, you do a monkey patch on the class on that method.

You do all these inside your new-app. You never touch the ERPNext or Frappe app code. This way, bench update will never complain, and if you have changes in your own code (and you have other sites that use this code), bench update will also pull in you own code updates.

3 Likes

If I need to change erpnext source code, I prefer to fork erpnext and update source code directly. That way I get a merge conflict when new updates touch my own customization, and I can adapt my code based on new features.
With monkey patch, I don’t know that code I replaced got updated, and it may create issues hard to identify.

1 Like

This is a complicated topic. I will try to summarize the 4 different approaches, beginning with the least-complex scenario.

1. Making changes with the “Customize” button.

To make simple modifications (changing a DocField’s label, adding a new Naming Series, adding a DocField to an existing DocType), you may decide to use the Customize button.

When using this button, your changes are saved –in the SQL database– of your Site. The ERPNext code itself is not touched. So no git logs. (Exception: you may optionally choose to export your Customizations to JSON files in an App).

Advantages:

  • Quick and easy to create minor changes.
  • No need to think about git.

Disadvantages:

  • Cannot do any complex changes, or significantly change how ERPNext behaves.
  • Because the changes are stored in the database, the visibility of changes is “obscured”. There is no command like git diff that will show a developer Before vs. After. To understand what’s happened requires reviewing certain SQL tables and JSON files, and trying to grasp the original intent.

2. Writing your own App

If you need to --add-- to ERPNext (but not modify the existing functionality), you can decide to create your own App. Create new DocTypes and DocFields for your App. Write any necessary Python and JS code. When you’re ready, install the App on your Site.

You should definitely create a git repository for your custom App. But this repository will be entirely separated from the Frappe and ERPNext repositories.

Advantages:

  • You can create new ideas, features, and functionality.

Disadvantages:

  • You cannot modify what’s already in ERPNext. So you’re still limited by the Frappe framework’s code, and the ERPNext code. You can interface with them. But you cannot change them…

…unless you go with Approach #3:

3. Extending your App with ‘hooks’ and ‘fixtures’

To understand this approach, you must comprehend the fundamental nature of the Python and JavaScript programming languages. They are “interpreted” languages (sometimes called “scripting” languages). The code you write isn’t compiled into a binary executable. Instead the code stays in plain-text files. When your program runs, the Python/JS interpreter compiles “just-in-time”, before the code is required.

This behavior produces an interesting possibility:

  1. You can write custom code in your App, which exists in your code files.
  2. At runtime, your code “overrides/appends” the official ERPNext code.

This process is informally known as ‘guerilla patching’ or ‘monkey patching.’. It’s a bit of cleverness to change code behavior, without changing code files. Using this patch trick, you never edit the official Frappe/ERPNext code. But you still get the desired modification.

Advantages:

  • You can create complex modifications and customizations.
  • No changes to the official ERPNext code. No forking, or git comparisons/merging.

Disadvantages:

  • You still have to put thought and effort into maintenance. When the official code changes (v12 → v13) your ‘monkey patch’ code will not be aware of this. Will the new, official changes break your patch code? Maybe. Maybe not. You have to test and review, to make sure your patch is still correctly implemented.
  • It’s challenging for a 3rd party developer to login, and understand how ERPNext is behaving differently. You cannot run a git diff command, and view Official vs. Custom code. The code is now maintained in 2 places (official, patch). Hopefully the developer of the patch code does a good job documenting their changes.

4. Fork the official code, and maintain your own changes.

Finally, there is the “traditional” way of performing modifications, without patch code, hooks, or fixtures. You fork the official code. Create your own git branches. Modify whatever you want. And maintain your own fork from now on.

Advantages:

  • This process is well-known, and well-documented. You’ll find countless articles and programs on the web for dealing with this.
  • If you want to view differences between your ERPNext, and official ERPNext, just do a git diff command. You can quickly view a side-by-side comparison with GUI tools.

Disadvantages:

  • You must maintain your own forks. This is not always easy or desireable.
  • When synchronizing, you must handle the git merge process, often requiring you manually edit code files. This may be time-consuming. If so, you may choose to update your ERPNext less-frequently.
  • Further reading:

Summary:
With great power, comes great responsibility.

The Frappe Framework offers many tools and methods for accomplishing your goals and needs. There is rarely a “right way” of accomplishing something. You have Options and Choices. Do what works best for you.

Personally, I usually write Custom Apps when I need to add functionality. But when I need to modify things, I usually choose Approach #4 (fork it). I dislike guerilla patching and Customization, for some of the reasons @guimorin mentioned.

13 Likes

Having worked on a custom implementation for the past year, I would highly recommend using separate Frappe apps wherever possible instead of editing ERPNext directly. I have not needed to edit ERPNext code directly.

Certain methods can be overridden in hooks.py and document events can be caught and managed properly. Any customization can also be exported as described above.

2 Likes

I think this is incorrect. Hooks and fixtures are NOT monkey patching. You use hooks and fixtures when you want to preserve your own customization. (You may also use hooks and fixtures in your No. 1 if you want to copy your customization to other sites.)

Hooks and fixtures PRESERVE the functionality of underlying Frappe / ERPNext classes. All their def methods will execute at the right moment, while your hooks and fixtures code will add on to what they did.

Monkey patching is done when you absolutely need to throw out / cancel out / eradicate / replace a certain ERPNext method.

For example, if Immutable Ledgers did not allow backdated entries, you may resort to monkey patching to code your own def - replacing the def of ERPNext – without touching ERPNext code.

1 Like

I will never fork ERPNext / Frappe branches UNLESS it is to contribute to bug fixes, or to contribute new functionality to ERPNext.

For example, a good fork is a Chart of Accounts Importer that allows use of Account Number of Parent Account (instead of the current Parent Account Name). You can fork ERPNext, directly change the json, py and js codes of ERPNext, and you push the changes to the Main ERPNext code. The Frappe team will will interact with you and eventually add your code to ERPNext or decide not to accept your code.

Another example is, if you read in discuss.frappe.io about mis-aligned column headings in certain financial reports. You work on the code to fix the bug. You push the bug fix to ERPNext. Frappe team will check your fix. If it is good, then it gets into the ERPNext code.

This way, we are all assured that there is a team that manages the code base and there is no free-for-all like what was experienced in Compiere branches and forks.

If your changes are client specific, you have to make your separate app to preserve the changes for your self. If the functionality “adds on” to existing ERPNext functionality, you use hooks and fixtures. If you need to throw out specific ERPNext functionality and put in your own, you use monkey patching.

I do not detail how these are done here. But I just want to show that everything is possible, and do it - in my opinion - the safe way.

As just a complementary information, with the override_doctype_class on v13, you are able to “override” methods using herence, what works pretty much like monkey patching, and works really well!

https://frappeframework.com/docs/user/en/python-api/hooks#override-doctype-class

But the sad, it, no support to v11 or v12

1 Like

This is good to know.

This is indeed helpful. Would you be kind enough to write up a detailed document with code examples. It would benefit the entire community extensively.

Frappe / ERPNext is a mesh (not mess - but mesh - orderly) of js, json, python, html, css. and sql. I can say it is best in class - given the components it uses. The code is so good that it gives you things are are supposed to be very difficult to achieve by other frameworks using the similar setups (like json nosql-like data structures despite using relational databases).

It is not trivial to change the functionalities contained in Frappe / ERPNext. That is why before doing any monkey patch, you must know what you are doing, and you must review the Frappe / ERPNext code to make sure that you will not miss out on any goodies – or you must include them in your code.

Because of this, I think it is not good for me to show examples because it might give the impression that this is easy. It is not. But – because Frappe / ERPNext is open source, you are not locked in. You have possible ways of achieving your objectives, but benefit from the hard work of Frappe Team. Thanks to RMehta’s generosity and vision.

Appreciate your pointing to override_doctype_class Its really a nice pointer to accommodate and would be helpful. If experts express some thoughts/pointers and whether/how to override default class of document with help of server-side script introduced in version 13

Thanks, You nicely explained the best scenario to be used frappe/ERPNext and it depends on need, and client-specific needs are very important to move forward.

We have to use the custom app with our own fork of ERPNext ( not frappe) and develop the functionality but fetch changes from other repositories and origin too. Yes, You are an expert so request to highlight scenario 4
@Piyush_Mantri

Absolutely true ! Some clients demands complete solution as they are perfectionist . So how we can deliver the complete solution ensuring that we can always take care changes/enhancement on ERP Next.

The major issue about Fork or not Fork is in the long therm!

Im consultant for 2 customers that decided to fork ERPNEXT few years ago, and delevop they own solution around that.

They did so heavily customizations on the begnning that, right now, they need to have 2 development teams, one to analyse new features joining on ERPNEXT and backport they, and other just to develop new features!

They are under tabaco manufacturing and Telco.

So rightnow, I have they plans in hand for backport features from v-13 to they forks (v5 and v7 respectively), its more than 4 months of hard work, to make backports, without take into consideration, bug fixes, new features during the development.

Also, I saw that they release plans are always delayed, because, testing and ensure that everything will work, when you are dealing with a patchwork system is a completely nightmare!

Keep in mind, that these 2 cases, are companies that decided to fork ERPNEXT for they usage, só, could you imaging the overhead maintain a fork introduce to IT Service companies?

In terms of good pratices, apps are the way to go.

Like @Joseph_Marie_Alba1 said, explore the code, do small changes, and read the docs, it will easy the things for you in the long term!

And the best thing about Frappe / ERPNext is that through apps, you can code your own thing into the mesh

1 Like

This is the reason why I advised strongly against touching Frappe / ERPNext code unless you plan to submit it to Frappe team for inclusion.

Apps is the power for Frappe. It allows you to maintain different customized businesses without mixing up one with the other. It allows you to be Agile and immediately deliver code.

Can you imagine if ERPNext itself broke the domains into Frappe apps? More specialized businesses like telecom, tobacoo would be able to easily share their codes because functionalities are contained within the apps.

2 Likes