MEP 6 - ERP
- Author: Rodda John
- Status: Adopted
- Adopted: 2024-03-27
Overview
An ERP (enterprise resource planning) is a piece of software that tracks the flow of goods, services, and money through a company.
Modern ERPs operate on the principle of double-entry accounting whereby every credit has an associated debit.
A credit or a debit could result in either an increase or a decrease, that follows the following rules:
Account types:
- Asset accounts
- Debit: increase
- Credit: decrease
- Expense accounts
- Debit: increase
- Credit: decrease
- Liability accounts
- Debit: decrease
- Credit: increase
- Equity accounts
- Debit: decrease
- Credit: increase
- Revenue / Income accounts
- Debit: decrease
- Credit: increase
Modeling
Account
- Name
- Active (Y/N)
- Classification (one of the account types above)
- Type (see this)
- Sub Type (see this)
- Account number (alphanumeric, no colons)
- Parent account (nullable, applicable if this is a sub account)
Journal
account_id(which account is the transaction associated with)- reference number
- credit / debit
- amount
- Nullable fields
- location-id
- customer-id
- vendor-id
- order-id
- asset-id
Journals should follow the following constraint:
SELECT SUM(journals.amount) = 0 FROM journals GROUP BY
journals.reference_number;
A balance check is trivial to run:
SELECT SUM(journals.amount) FROM journals GROUP BY
journals.account_id;
To retrieve more specific information:
- e.g. sum all journal entries related to asset XYZ in a fixed asset account - accumulate depreciation account
Generating a balance sheet is trivial, simply get a sum of all accounts, display taxonomy
Getting a full report on a customer, vendor, item, order, is trivial as you just filter journals by that and then group by
Editing a journal amounts is normally possible if we're in an "open period" – we don't really have that concept, they're always editable as long as they zero out.
Editing a customer, vendor, order etc, is equally thus very possible whenever.
Integrations
This is already built.
Store an AccountingAccess model that understands how to authenticate
and connect to external vendors. Store a RemoteObject model that
stores objects in the foreign ERP locally so as to allow FKs. There
is a task that syncs this
A customer, vendor, account, asset, order, etc can be linked to a remote object
A journal entry has a sync status column, all journals with the same reference number are synced at the same time.
Unsynced journals are polled and a sync task is persisted to postgres, this allows for rendering errors etc.
Third party limitations:
- Quickbooks requires a customer for AR postings
- Quickbooks requires a vendor for AP postings
Syncing
Terminology:
- "Remote state" the actual remote state
- "Remote model" the DB tables that track external state
- "Local model" the DB tables that track Moab's objects
"Mappings"
- Accounts
- Customers
- Vendors
For mappings, on every pull of remote objects:
- For new objects in remote state not in remote models, create remote models
- For updates to remote models, update them
- For remote models without local models, create local models, and link via FK to remote model
- There are no deletions, they're just marked as inactive
- If any are marked as inactive, mark the remote model as inactive
- For remote models marked as inactive, mark the local model as inactive
For mappings, when a new local model is created:
- Create a remote state, create a remote model, link (important so as to not doubly create)
For mappings, when a local model is updated:
- Create a queue object to sync state of a local model to the remote state
- On sync, update the remote state, and update the remote model
"Syncs" Syncing refers to the process of syncing GLs to external ERPs.
For every GL Moab wants to write, create a local model journal
- Thus, the Moab GL is up to date
There is a batch sync table that displays unsynced GLs in a few different statuses:
- Missing mapping
- There is an object this entry depends on (customer, vendor, GL), that doesn't exist on the remote side – this shouldn't really every happen
-
Waiting
- When the accountant marks this as "ready", it gets picked up in a batch and is synced over
-
If you edit a journal entry, you can edit anything about it, but it must still 0 balance out.