Enterprise Resource Planning on Purescript?

Many small businesses need an ERP. The common purpose of such a system is to track invoices, but it’s varying a lot what these systems do. It’s important for such systems to remain functioning for long periods.

I realised that if you had some simple libraries, it’d be a relatively easy and a nice task to maintain an ERP. I believe it’d be sufficient to have the following libraries:

  • Database/dataset management/data backup tools
  • Templating, template building, paper/email/PDF/HTML printouts from the system, report construction.
  • Form building, user interfacing
  • Security/logging/user access control if the system is online
  • Bignum, exact arithmetic
  • Smaller libraries to uphold common rules and practices with bookkeeping, on top of the earlier libraries.

Purescript might be a good fit for this kind of software, because if you look at the above list, could it be that it’s inevitable that Purescript community eventually implements these libraries for various reasons?

I know you’ve provided lot of libraries, and it might be that the whole above list is already covered. Have you experimented with anything that could be counted as an ERP?

2 Likes

Lumi’s platform is more or less an ERP. Our backend is all Haskell, though; it’s just the frontend which is written in PureScript. Here are the PureScript versions of those things which we use in production:

  • A separate templating language isn’t really needed (I would argue) when you have one of the UI frameworks like halogen, concur, or react-basic. (For us, PureScript isn’t involved in PDF printouts; we handle those by rendering to HTML on the server via Haskell’s hamlet library and then running it through wkhtmltopdf if I remember correctly.)
    • If you really really want to use JSX, you can always use the FFI, and write your component logic in PureScript and your render functions in JSX. I haven’t done that myself, though, and I think it might end up being a bit awkward.
  • Forms are covered by our lumi-components library: https://pursuit.purescript.org/packages/purescript-lumi-components/14.0.0/docs/Lumi.Components.Form
  • We use fixed-point arithmetic for currency calculations: https://pursuit.purescript.org/packages/purescript-fixed-precision/4.3.1/docs/Data.Fixed#t:Fixed. Exact arithmetic often isn’t desirable, in my view – the difference between “accurate to 15 dp” and “exact” is pretty much negligible, but fixed-point is simpler implementation-wise (= faster and more predictable memory usage) and is implemented by databases, so that you can perform calculations inside the database as well.

I definitely think PureScript is a good fit for this kind of thing! The other things you listed are more backend concerns so they’re mostly handled in Haskell.

4 Likes

Regarding PS backend pieces I can link to some libs. Some more and some less mature. I’m involved in many of them and I’m really happy to push them forward.

Database/dataset management/data backup tools

There are multiple options: purescript-selda + purescript-postgresql-client (we use this stack) or purescript-node-postgres, purescript-redis, purescript-mongo (I haven’t used that yet)

Templating, template building, paper/email/PDF/HTML printouts from the system, report construction.

Following Harry suggestion I would probably go with react-basic + renderToString (the usual way of SSR for react) but there pure PS based html templating lib with monadic DSL called smolder. I’m biased but I would probably pick react-basic-mui for UI components and make some contributions to the lib as well :stuck_out_tongue:
Regarding pdf rendering we have started building bindings/DSL for the pdfmake here and want to move it forward soon.

Form building, user interfacing

We use polyform (Applicative + Category based validation) as a base layer, polyform-batteries as a form independent validators set and finally I want to finish and extract a form DSL package from the webrow sometime soon.

Security/logging/user access control if the system is online

I have written minimal but working PS bindings for the node module for systemd journald plus some glue lib which connects it with purescript-logging.
We have also a stub for sentry logger based on the old sentry API which requires a rewrite. Of course it is a matter of binding again because sentry provides nice lib for the node and for the browser :wink:
Regarding security there are multiple options for crypto stuff on the backend. I know two libs for the jwt handling plus we have some examples for cookie based session handling here and here).

2 Likes

I’ve been building customisations for existing ERP (E-Business Suite) and ERP systems from scratch for years now. And I’ve started using PureScript and Haskell a year ago for my newest exploratory projects.

Besides switching to functional programming, I’ve been using event sourcing instead of the more traditional DBMS architecture for these projects. Event sourcing simply is a left fold on an immutable, append-only log of events that have happened in the system to derive the current state.

I can say that ERP / accounting like applications benefit enormously from this architecture, because business processes tend to be event based (and the business involved in these processes often already tend to think in terms of events). Furthermore, accounting is normally already event sourced, the ledger is nothing more than an immutable log of transactions.

My new systems also use a slightly different type of user interface: instead of building CRUD views, I tend to think in terms of actions that a user wants to perform, which made my applications much easier to learn and reason about for end users.

For the programmer it also becomes easier to create asynchronous processes, which in the ERP community is commonly called workflow. For example: mark an open supplier invoice ready for payment once the goods have been received. You can easily perform this action when the “GoodsReceived” event has entered the system, and create a new event to mark the invoice payable.

There are many other benefits of event sourcing:

  • Auditing (important for financial data)
  • Synchronise data with mobile clients for offline operation becomes easy: just download the missing events from the event log and replay them on the locally cached data
  • Time travel debugging

I have been hacking on my custom event sourcing backend written in Haskell and a front end written in PureScript / Halogen. This is all very much work in progress but I’ve already have some bits available on my GitHub. If people are interested I can expand more on it.

2 Likes

I agree that event sourcing sounds like a good approach. It fits how lot of things such as orders and invoices work. Also I like that it leaves a log that explains when something changed and why.

The actions -approach is also a bit interesting. I tend to think of types themselves forming user interfaces. We could make this a really concrete design.

After looking at few Haskell HTML templating & generator tools, I think I’ll try to build my own and see how it turns out. I remember that long time ago I wrote something that I can repurpose. I’ve liked to create templates and then fill them up with beautifulsoup. I also like this thing about the interfaces being type-checkable, that should help out a lot in potential use-cases like these.

There’s lot of stuff in here that seems interesting.

I use Halogen in combination with Formless for templating. I also use Higher Kinded Data for my events types. This allows me to very easily create/update data that is usually created using CRUD. I also hope to tie together my data types and validations this way (also work in progress).

I hope to create a simple accounting application in PureScript that uses event sourcing (on top of my Apie backend, although that should be quite easy to swap out) in the coming weeks. When I’ve something ready I will post it on this forum.

2 Likes