You can use a QR code to open a specific MDriven Turnkey view and pass a value into that view, so a phone user can continue a workflow for the intended business object.
A QR code holds a URL. In a Turnkey application, that URL can target the DisplayWithVariables route, select a ViewModel, and supply one or more ViewModel variables. For example, print a QR code on a complaint document; when the customer scans it, Turnkey opens a complaint view and searches for the complaint number carried in the URL.
How the workflow works
The workflow has four parts:
- A derived image attribute generates a QR-code image from a URL.
- The URL opens Turnkey with
DisplayWithVariables. - The target ViewModel receives a value in a named variable.
- A periodic action detects that value, performs the search once, and then stops itself.
| Part | Purpose | Example |
|---|---|---|
| QR-code image | Gives the user a scannable entry point. | A QRCode: Blob attribute renders a 300 Ă 300 image.
|
| URL | Identifies the Turnkey site and target view. | https://example/MDriven/DisplayWithVariables?view=ComplaintFromCode...
|
| ViewModel variable | Carries an object identifier or other input into the view. | vComplaintNumber
|
| Periodic action | Reacts when the variable has a new value. | It searches for the complaint, records the processed value, and becomes hidden. |
Prerequisite: enable QR-code generation
Configure the ZXing model pattern before you add the derived attribute:
- Add a class named
ZXing. - Add the static operation
QRImage(width:Integer; height:Integer; value:String):Image. - Mark the operation as
IsQuery. This promises that the operation does not change model-object state and permits its use in OCL expressions. - Set the operation tagged value
Eco.ExternalLateBound = AnyValue.
The QR-code generation pattern does not work in a server-side job. For the complete generation setup, including EAN13 barcodes, see HowTos:Generate QR Codes in Turnkey.
Create a QR-code image for an object
Create a derived Blob attribute on the class whose workflow you want to open. Set its BlobType to Image so that Turnkey treats the result as an image.
For example, a complaint object with a Lopnummer attribute can have this derived attribute:
QRCode: Blob
DerivationOcl = ZXing.QRImage(300,300,
'https://reklamation.azurewebsites.net/MDriven/DisplayWithVariables?view=TestQRCodeFromVariable&id=$null$&vLopnummer='
+ self.Lopnummer.asstring)
This expression does the following:
ZXing.QRImage(300,300,...)creates a QR-code image that is 300 by 300 pixels.- The URL targets the applicationâs
/MDriven/DisplayWithVariablesroute. view=TestQRCodeFromVariableselects the target view.id=$null$supplies no root-object identifier to the view.vLopnummer=names the ViewModel variable to set.self.Lopnummer.asstringappends the current objectâs complaint number as the variable value.
Replace the site address, view name, variable name, and object value with values from your own application. Keep the variable name in the URL identical to the variable name in the target ViewModel.
Build the receiving ViewModel
Create the target ViewModel named in the URL. It needs:
- A variable that receives the URL value, for example
vLopnummer. - A second variable that records the value already processed, for example
vSearchIsPerformedOn. - A search action that uses the received value to locate the intended object.
The second variable prevents the action from running continuously. It turns a change in a ViewModel variable into a one-time trigger.
Configure the one-time search trigger
Add an action that performs the search. Configure it with:
| Action property | Value | Why it is needed |
|---|---|---|
| Interval | 100
|
Re-evaluates the action while it is visible. |
| Visible expression | vSearchIsPerformedOn<>vLopnummer
|
Shows and runs the action only when the received value differs from the processed value. |
| Execute expression | Search, then assign vSearchIsPerformedOn:=vLopnummer.
|
Records that this value has been handled, causing the action to become hidden. |
In the original complaint example, the execute expression first invokes selfVM.Search and then sets vSearchIsPerformedOn:=vLopnummer. Once both variables are equal, the Visible expression is false, so the periodic action stops.
This pattern is useful beyond QR codes. Use it whenever a ViewModel action must respond once to a changed variable value rather than run repeatedly.
Publish and use the QR code
Display the derived image wherever users need it. Because it is an image Blob, you can include it in a grid, report, printed output, or another form. QR codes must be large enough to scan reliably; Turnkey image style references include small, medium, and large, which can be adjusted through CSS.
A typical flow is:
- A staff member opens a complaint and displays or prints its QR code.
- A phone user scans the code with a QR-code reader.
- The reader opens the Turnkey URL.
- Turnkey opens the selected view and assigns the URL value to
vLopnummer. - The periodic action searches for that complaint once.
- The user sees the complaint-specific workflow and can perform only the actions that the view and access rules allow.
The same approach can support field workflows. For example, a QR code on a tool can open a tool-assignment view, allowing a field user to identify that tool before checking it out. QR codes are also suitable for participant entry points such as the mobile poll in Documentation:Turnkey sample InstantPoll.
Control access and protect identifiers
A QR code is a URL that can be copied, forwarded, or photographed. Do not treat possession of a code as proof of identity.
If you make the target view available without AccessGroups, anyone who obtains the URL can reach that view. Restrict the actions and information exposed there accordingly. In particular:
- Do not expose sensitive data only because an identifier is difficult to guess.
- Do not rely on a sequential number such as
Lopnummeras an access-control mechanism. - If your workflow needs an unguessable link value, use an identifier designed for that purpose, such as a generated Guid, and still decide which actions the recipient may perform.
- Test the target URL in a private browser session to verify what an unauthenticated user can see and do.
For a complete example that includes QR-code-based customer access in complaint handling, see Documentation:Store complaint handling.
Troubleshooting
| Symptom | Check |
|---|---|
| The QR image is not generated. | Verify the ZXing class and exact QRImage(width:Integer; height:Integer; value:String):Image signature. Confirm that the operation is static, marked IsQuery, and has Eco.ExternalLateBound = AnyValue.
|
| The expression is not accepted in OCL. | Confirm that QRImage is marked IsQuery and that the URL expression produces a String.
|
| Scanning opens the application but not the expected view. | Check the application base URL, the /MDriven/DisplayWithVariables path, and the exact value of the view parameter.
|
| The view opens but does not search. | Confirm that the URL parameter name matches the ViewModel variable name and that the periodic actionâs Visible and Execute expressions use the same variables. |
| The search runs repeatedly. | Ensure the action assigns the processed-value variable after searching, so the Visible expression becomes false. |
| The code is difficult to scan. | Use an appropriate image size and verify the printed or displayed result with the intended phone and QR-code reader. |
