Offline POS in ERPNext is great. The user response time does not rely on your network latency at all and the interface is very responsive.
But it’s not TRULY offline. The user still needs internet access to load up the POS screen and the user cannot cannot reload POS page if the system or your internet service is down.
I’m not sure whether such a demand for truly offline POS warrants the efforts needed to implement such a thing.
For one of my customers, I actually created a stand alone POS app using VueJS. A few design decisions about the app -
- It uses service workers for offline availability and IndexedDb to store offline data
- It resides in a separate domain from ERPNext. This is because making frappe framework pages loadable offline is a pain and almost impossible. I also looked into frappe framework’s URL routing code and everything seems hard-coded to basic URLs like /login and /desk. Modifying this feels way too intrusive and just setting up a separate site with CORS configuration added to ERPNext nginx seems easier.
- POS PIN code field added to employee to handle offline authentication. These codes are stored in IndexedDB with clear-text so are OAuth tokens. May be there is a way to make this more secure.
This way, there’s really no need to install client apps on POS terminals and once the POS profile is setup, POS user needs only to access the POS app URL once and login using his/her actual ERPNext account once to setup the POS terminal.
Needless to say, the App is rushed out to meet the deadline and a lot of the parts are very hacky, especially when it comes to system defaults and print templates. The POS app does not cover the full sales features of ERPNext and only cover the specific features.
But I do have some ideas for ERPNext’s built-in POS to be truly available offline.
First, it would not be a frappe framework’s hash loaded page. It would be a “first level” link like /desk or /login pages. This means something has to be done about frappe framework’s first level URL routing. If we are to hardcode /pos to frappe itself, ERPNext app’s specific link would be intruding on frappe. Ideally, frappe should have some way to allow it’s apps to add additional first level URLs.
Service workers will be enabled for POS specific client-side resources.
Currenty POS page will be updated to use IndexedDb instead of localStorage. This might entail quit a bit of efforts because indexeddb operations are asynchronous and the offline POS data schema also has to be revised to work well with IndexedDb.
We can also probably do away with OAuth in this case. The reason I had to use OAuth in my app is because of the CSRF token. If the user open both my POS app and ERPNext desk, the CSRF token got generated and ERPNext expects every calls to include this token except OAuth calls.
If you think such efforts warrant the additional use cases for end users (like event booth sales), please share your thoughts, add to the discussion and I would be willing to work on it. But I would struggle with the python side of things, especially frappe. If someone would be able to help with frappe URL routing, that’d be great.