This article was moved to MDriven Wiki – QR-Code to drive a workflow in any MDriven turnkey app
QR-Codes can hold urls and as such they are a great binder between the outside world and your information system.
Imagine a standard QR-code-reading-app on anyone’s phone being the entry point deep into your information – showing the user current state of something and asking them on how to proceed.
That was the basic pitch that Lars gave me and this article is how to leverage this ability in the current MDriven Turnkey release.
It turned out that there where a few things I needed to get straight to get the implementation the way I wanted it. I wanted the functionality to produce a QR-code to be easily accessible but I did not want it to be a new operator in OCL/EAL since that would clutter the language if we just add every good extension we come to think of that way.
I wanted to make it available as a static method on a class so that you could go like SomeClass.QRImage(theUrlToEncode):Image.
But static methods was not supported – so we needed to add that – fixed. You can now have methods in your model with OperationKind=static – and they will show up on the Class in EAL and also in OCL if you mark the method as IsQuery (then you promise to not change state on model objects so that the method is safe to include in OCL queries).
I could now go on to add a good QR-code library – and I could add it as an extension as described in this article. But I wanted it to be accessible for everyone running turnkey since I think it is such a crucial interaction widget. So instead I added a pattern that you can use in your model and when you use it we will provide the logic behind it. This is the pattern:
Add a class ZXing (this is the open source QR-code library we use, credits go to everyone involved in that). Add a static method with this signature QRImage(width:Integer; height:Integer; value:String):Image – and then you have access. In the application (a returns and reclamation system) where this was used first we added a derived attribute like so:
QRCode: Blob , DerivationOcl = ZXing.QRImage(300,300,’https://reklamation.azurewebsites.net/MDriven/DisplayWithVariables?view=TestQRCodeFromVariable&id=$null$&vLopnummer=’+self.Lopnummer.asstring)
Let me explain the Ocl a bit:
ZXing.QRImage(300,300, theUrl) – this calls the static method QRImage on class ZXing, stating that the QRCode should be 300×300 pixels – in order for this to be legal in Ocl we must have the QRImage method marked as IsQuery.
The url we send in is a string made up of the Url of our application ‘https://reklamation.azurewebsites.net’ and then the path to the MDriven controller and then a new Verb: DisplayWithVariables. What this new verb does is exactly the same as the usual Display verb – namely takes a view name and a root id for that view. For now I use “view=TestQRCodeFromVariable&id=$null$”. What the new verb DisplayWithVariables offers beyond “Display” is a way to send in variable values that should be set in the view once. In my case I want it to to set a variable called vLopnummer in the TestQRCodeFromVariable view – and I want the QR-code to set the variable to the value of the attribute called Lopnummer of the reclamation that the QR-code belongs to: ‘vLopnummer=’+self.Lopnummer.asstring.
This means I now have a way to produce a QR-code that points to my app – a specific view in that app – and set a specific variable when entering that view.
I can then define this view:
It is a simple search view – the search button action has however been given an Interval=100 – this means it will execute repeatedly every 100 millisecs – as long as the action is visible. Since the Visible expression is “vSearchIsPerformedOn<>vLopnummer” the repetition will only go on as long as the vSearchIsPerformedOn differs from the vLopnummer. Once they are equal the search button will be hidden and the repetition will stop. And if we examine the search button’s execute expression we see that it first executes the search with selfVM.Search – then sets the variable vSearchIsPerformedOn:=vLopnummer – thus stopping further action. This is a pattern that is useable when needing to react with an action on data that change; use a periodic action that only runs when some variables differ – make the action set the variables so that they do not differ. It effectively becomes a trigger that executes once when some watched data has changed.
I can now have a view that produce the QR-Code – and email it or print it or some other way leave it somewhere. Then any person, with any smart-phone, that has an app that reads QR-codes can point and click to end up on my target page for the specific object I had intended:
I make this view accessible to everyone – leaving it out of any AccessGroups – it is then up to me to decide what actions to allow from this view. Is the “Lopnummer” considered hard to guess so that I can trust the holder of it to be the intended person? Maybe not – but what if it was a generated Guid instead – in a sea of billions of possibilities it will be hard to guess.
As the QR-code is treated as any kind of image (a blob with BlobType=Image) you can present it in grids or reports etc. Since the QR-code needs to be a certain size to be readable new stylerefs on images has been added; small,medium,large (changeable thru css).