I am rebuilding a software in accounting. This sofware can handle many types of transactions, e.g. sales, inventory restock, and expenses. I have no background in accounting, but I learned some concepts online. I am trying to model the domain with these principles in mind:
- A journal entry consists of several recordings, each of which is either a debit or credit. These recordings' total of debit and credit must be equal (balanced) in a given journal entry
- A journal entry must be created based off of a source document. One cannot simply create a journal entry without any reason.
From those, I conclude that there has to be these entities present:
JournalEntryentity, which has manyJournalEntryItemvalue objects. This entity is responsible for keeping all its entries in a balanced state.SourceDocumententity, which has some information of transactions being made
Both JournalEntity and SourceDocument are each an aggregate root, with JournalEntity referencing to a SourceDocument identity.
Now here is the problem. Source documents that are the basis of journal entry creation, can be different things with different behaviors. For example, an 'expense' source document may consists of list of pair of expense category and expense amount, while a 'sales' source document may consists of related inventories, amount of each inventories, and the price of each inventory per one unit.
This makes me think of another approach in the model:
- Create an abstract
SourceDocumentclass, with shared properties like date of creation and identity attribute - Create
SalesSourceDocument,ExpenseSourceDocument, etc., that are extended from the abstractSourceDocument JournalEntryentity will still have to referenceSourceDocumentidentity.
While this can make sense, I don't think this is the best way to model the problem in DDD, specifically because it requires to have an abstract entity.
From the sources I read online about DDD, when encountering such problem where I need an abstract entity, I need to separate it into different bounded contexts. However, I'm not sure if it can be done, because a SourceDocument identity may return a concrete SalesSourceDocument in 'sales' context, but it may also return nothing in 'expense' context.
What is the best way to approach this problem?