A core capability of the Clinical System i.s.h.med is to manage clinical documents. Regardless of the representation and structure of the contents, clinical documents share a common set of administrative data, including crucial reference data: which patient, case, movement or service does this document belong to? One has to specify the document reference level when creating the so-called document category, and the system then ensures that a document that has to be assigned to a case can't be created unless a case number is specified. During normal development and maintenance, most administrators tend to think of these reference levels as transitive: A case always specifies a distinct patient, a movement always uniquely identifies a case and so on. Unfortunately, that is not entirely true. It is possible to enter and process services that are assigned to a patient, but have not (yet) been assigned to a case. This might happen for example when planning services for a patient that will be readmitted in the future: The service is assigned to the patient, but nothing else. Normally, the user should only create documents and other clinical data after the admission has taken place and the case is created, but sometimes, things get mixed up. This lead to multiple documents that were created with reference to a patient and a service, but no case or movement reference, which in turn caused all kinds of subsequent problems.
Shades of Grey
(Billy Joel, not 50)
The first reaction to this situation was something along the lines of "We don't want any patient-level documents anyway: authorizations, treatment contract, can't be released ever - nah. Every document has to be assigned to a case. Can't you put something together that will prevent this from ever happening again?". A closer investigation turned out that - as usual - there's no hard-and-fast rule without its share of exceptions. In this case, there are two institutions with differing rules - for one institution, two document categories have to be excluded from this rule, while for another institution, three more complex sets of exclusions involving various combinations of document category and documenting organizational unit (OU) have to be considered. This already suggests that the exceptions might not only be a bit more complex than initially assumed, but that they might also be subject to substantial change over time since both document categories and organizational structures tend to evolve over time. Bottom line: Hard-coding this probably is not a good idea.
The Classical Approach
A common way of approaching this task is to define a transparent table that contains the combinations that are either allowed or forbidden, depending on the actual implementation. The table would be equipped with a maintenance view and a generated maintenance application, enabling entries to be changed and changes to be transported as required. While this pattern is already a lot better than hard-coding the logic directly, it still has some drawbacks:
You need to program the logic to read and evaluate the table contents. This might sound trivial, but with growing complexity, it doesn't stay trivial very long.
You can't easily express clauses containing "and", "or", "unless" and "only if" using customizing tables - you have to enumerate all possible combinations instead. Over time, this tends to lead to large sets of entries that may cause performance and/or handling issues.
If you want to support generic entries (*) or more complex conditions like "starts with ABC*" or "between DEF1000 and DEF1999", again you have to code this manually.
Today, we know that we need to consider the institution, the document category and the documenting OU, so this will probably have to be key fields of the table. If more or different criteria are needed to express the exceptions at some point in the future, the structure of the table will have to be altered. Depending on the complexity and actual implementation, this might lead to substantial changes in the code as well as adaptation of the table contents, adding to the overall effort of every change. Unintended side-effects of the change might slip in very easily.
It's usually not possible to add documentation to entries of a customizing table - in the best case, you can deduce what a certain entry does but not why it was made.
Unless you explicitly program it for yourself, there's no testing environment and no logging either, which makes it hard to verify the correctness of the contents of the customizing table and to weed out bugs in the implementation.
Given all these weaknesses, one should wonder - isn't there a better approach?
BRFplus is a Business Rules Framework, designed to handle applications just like this one (and much more complex cases as well). I won't even try to write yet another introduction to BRFplus, outlining all its capabilities and its outstanding flexibility in detail. There are quite a number of entry-level articles available, as well as a fairly comprehensive online documentation and some good books as well. I've got Business Rule Management mit ABAP by Thomas Albrecht, matthias.kucharska-huelsmann, christian.lechner, daniel.ridder, wolfgang.schaper, tobias.trapp and carsten.zieglerand can highly recommend it to get familiar with BRFplus. For the English-speaking readers, there's an older book still available - I no longer have access to this book, but I vaguely remember it to be of very high quality as well. No use repeating what's already been written by people far more knowledgeable than me.
So, instead of an introduction, here are a set of promises. If you use BRFplus to implement the business rules stated above,
you will be able to express the ruleset completely within a very reasonable amount of time,
you will gain an incredible amount of flexibility and thus be much better prepared for future changes,
you will be able to easily document the rules,
you will get the same transport facilities (if you want to) without any additional effort,
you will be able to use exemplary testing and tracing frameworks without additional implementation on your side and
you will get all this with very little ABAP coding involved, and whatever code is required is very unlikely to change.
Interested? Well then, follow me into the depths of the system and see for yourself.
Disclaimer: This article was supported by my current employer, St. Georg IT Gesellschaft mbH.