Instruction Files
Instruction Files
Introduction
Bar|Scan has functions designed to help the Bar|Scan administrator send messages to other Bar|Scan users and facilitate logouts by those users. In addition, there is the ability to do formatted imports on a regularly timed basis. More functions may be added in the future.
How It is Done
Whenever a user starts the Bar|Scan application, the application will regularly check for new instruction files to load every two minutes or so. Instruction files are just text files with both data and instructions contained within them. When Bar|Scan executes an instruction file it is just doing what that file tells it to do, using the embedded instructions and data to get the job done. These instruction files have their own system folder for all of the operations related to them. The name of the system folder is SYSQ. Within this folder there are two subfolders, SYSQIN and SYSQOUT.
Instruction files meant to be loaded into Bar|Scan must be put into SYSQIN. When the operations in an instruction file have been completed or the instruction file has ‘expired’, a modified copy is put back out into the SYSQOUT folder. It has been ‘Dequeued’.
How long the instruction file is kept in the Bar|Scan internal instruction queue depends upon the nature of the command and how long the instruction file itself says that it is to be retained.
Typical Process
The typical successful instruction goes like this.
- The Bar|Scan administrator decides to perform an instruction. (Such as send a message to a particular user to log them out.)
- The administrator creates a new text file starting with ‘bs’ with an ‘xml’ extension (these are requirements, e.g. bsMsgToEarl.com).
- They edit the file according to the requirements of the particular instruction (see below).
- Once done editing the file, they will copy the file into the SYSQIN folder or they may do a drag and drop.
- Within a short time (within 2 minutes) the file will disappear. This means it has been loaded into the instruction queue. An exact copy will appear in the SYSQOUT folder, but with the load time appended to the filename. (e.g. bsMsgToEarl_2020_10_10T15:33:00.xml)
- Finally (and depending upon the timing parameters included in the instruction file) the intended user will execute the instructions in the file. Of course, if the intended user is not logged in to Bar|Scan, they can neither receive messages nor execute any other instructions.
- If the instructions are to be executed only once, they will be immediately dequeued into the SYSQOUT folder. If they are to be repeated they will stay in the instruction queue until the expiration time contained within the instruction file. Then it will also be dequeued. The dequeued filename contains the original filename when loaded, as well as the date and time dequeued and the word ‘DEQUEUED’.
Detailed Requirements and Capabilities
An instruction file dropped into the SYSQIN folder can currently do any of the following 4 operations:
- Send a message to any or all Bar|Scan users.
- Do a formatted import.
- Force a logoff of any or all Bar|Scan users. (This has restrictions mentioned below.)
- Forcibly dequeue all items in the instruction queue (this is for administrative purposes).
Here are some facts that you need to know:
- A user can’t execute an instruction or receive a message if they are not logged in. If they are sent a message and they are not currently logged in they will only receive the message AFTER they log in to Bar|Scan. It is the same for any other instruction: the instruction will not be done until they have logged in to Bar|Scan. For example, if an operation is timed to be executed by a user at a given time, but that user is not logged in at that time, then the operation can not be performed unless they log in. Additionally, there is a small window of opportunity for each timed operation. If they are not logged in during that window of time then the operation will not be done and it will wait for the next start time.
- Instruction files are just properly formatted XML files. The xml file must begin with the two letters ‘bs’ and end with the extension ‘xml’. E.g. “bsShutdownAll.xml”. Any files not ending in ‘xml’ and starting with ‘bs’ will be ignored.
- All users scan the SYSQIN folder approximately every two (2) minutes. In practice, this will be longer, perhaps two to three minutes. The reason for this is that the workstation timer is affected by whatever is currently happening on the user’s workstation.
- If there is a problem consuming a particular xml file one of two things will happen:
- A similarly named file with the extension ‘prb’ will appear in the SYSQIN folder. This will give a clue as to why the system cannot read the file.
- The file will just sit there without being consumed. In this case Bar|Scan (for some reason) is not able to consume the file and is also not able to give you a reason why. The file should be removed and examined for problems.
- If the file is successfully consumed, then a copy of the file will be sent to the SYSQOUT folder with the time of consumption appended to the filename. E.g. if the current date is September 20, 2020 and it is 4:30 pm then bsSimpleMsg.xml will appear in SYSQOUT as bsSimpleMsg_2020-09-20t16_30_47.xml. This is a way to double check that a file has been consumed successfully.
- Each of the available instructions has its own required set of instructions, data and formatting. (See “How to Make an Xml File” below.)
- When the forced logout instruction is sent to other users there are many situations where they will not actually be forced to log out right away.
- If they have no pending edits and are not in the middle of any of the button operations they will be logged out. (Note: the buttons at the bottom of the screen panel contain the button operations. These include the navigation buttons, print buttons image buttons and any other buttons specific to a particular screen)
- If they are not in the middle of any of the button operations but they do have edits outstanding they will be prompted for whether or not they want to save them, then logged out.
- If they have activated any of the button operations (such as ‘print’, ‘commit’, ‘Go top’ etc.) then the forced logout operation will not begin until the button operation is complete. The logout will proceed according to the rules specified here above.
How to make an Instruction (Xml) Queue File.
The Instruction files must have a specific format to work correctly. They are simple text files, but each type of message has its own command and set of minimum values. They must also be valid xml files. All Instruction files internally must have at least the following, where COMMAND is the basic command and INITIALS is who is to execute it.
<?xml version = “1.0” encoding=”UTF-8″ standalone=”yes”?>
<VFPData>
<qcursor>
<qd_cmd>COMMAND</qd_cmd>
<qd_userid>INITIALS</qd_userid>
</qcursor>
</VFPData>
Note that each instruction with its command and data exists between the <qcursor> and </qcursor> tags. Also, every piece of data, every embedded command and every label must be between the leading and trailing tags that describe it. For example, all ‘commands’ must be between <qd_cmd> and </qd_cmd>. (e.g. <qd_cmd>SHOWMSG</qd_cmd>) Additionally, as you examine the list of instructions below you will note that each has a set of required fields and a set of optional fields. Keep in mind the following.
- Case matters. All tags must be lower case.
- All commands require a command tag and a user id tag:<qd_cmd>, <qd_userid>
- All commands can have the following optional tags:<qd_label>, <qd_buttons>, <qd_prompt>For an explanation of these see the SHOWMSG command below.
- All commands can have the following options, but they can only appear in the FIRST command of the file or they will be ignored.<qd_when>, <qd_everyn>, <qd_everyu>For an explanation of these see the IMPORT command below.
Command Short List
Here is a list of the available commands that can be specified between the <qd_cmd> and </qd_cmd> tags. Abbreviations will not be recognized.
- SHOWMSG – Sends a message to any or all Bar|Scan users.
- IMPORT – Runs a formatted import in the list of formatted imports.
- SHUTDOWN – Forces any or all users to logout.
- DEQUEUE – Removes pending commands from the Instruction Queue.
Here are the minimum sets of fields that need to be specified for each command. They are listed with a valid xml example.
Send a Message (SHOWMSG)
<qd_cmd> This requires the exact string ‘SHOWMSG’ (not including the quotes).
<qd_userid> Specify the login initials of the person to send the message to. They are the ones listed in the Bar|Scan User table.
<qd_prompt> Specify the message that you want to send.
Optionally:
<qd_buttons> ‘O’ sends the message to the specified user in the form of a dialog box with an ‘Ok’ button. They must click on it before proceeding. This is the default if no <qd_buttons> option is included.
‘P’ sends the message to the on-screen message list. It will stay there until cleared by the user.
‘YN’ sends the message in the form of a dialog box with a ‘Yes’ button and a ‘No’ button. This option allows the user to select between two different commands. ‘Yes’ executes the command whose label is specified in the optional <qd_onpass> field. ‘No’ executes the command whose label is specified in the optional <qd_onfail> field. If the selected <qd_onpass> or <qd_onfail> fields are empty or not listed then processing stops. If the label specified within them can not be found, processing also stops.
<qd_onpass> Enter the label of the command to execute next if the user selects ‘Yes’ as specified under <qd_buttons> above.
<qd_onfail> Enter the label of the command to execute next if the user selects ‘No’ as specified under <qd_buttons> above.
<qd_label> Give this command a name so that it can be referenced by other commands.
For Example: The message ” Please see me after lunch about your raise. Ed.” will appear on the screen of user ‘MAS’ as a dialog box with an ‘Ok’ button for the user to click on if they are currently logged If they are not logged in it will appear when they log in.
< ?xml version = “1.0” encoding=”UTF-8″ standalone=”yes”?>
<VFPData>
<qcursor>
<qd_label>SAMPLEMSG</qd_label>
<qd_cmd>SHOWMSG</qd_cmd>
<qd_userid>MAS</qd_userid>
<qd_buttons>O</qd_buttons>
<qd_prompt>Please see me after lunch about your raise. Ed.</qd_prompt>
</qcursor>
</VFPData>
Dequeue Messages (DEQUEUE)
<qd_cmd> This requires the exact string ‘DEQUEUE’ (not including the quotes).
<qd_userid> Specify the login initials of the account of the person that will do the Dequeueing. Normally this would be a master user. The initials are listed in the Bar|Scan User table.
<qd_item> ‘ALL’ will Dequeue all of the messages residing in the Instruction queue. They will be sent to the SYSQOUT folder with the word DEQUEUED in the name of the file along with the date and time dequeued. Currently the <qd_item> option with the word ‘ALL’ is required. There is no way to dequeue only a subset of the Queue by means of a command.
Optional:
<qd_prompt> Specify the message that you want to send prior to execution of this command. Like all commands, an optional message can be sent before execution of the command. The message follows the syntax, properties and requirements of the SHOWMSG command for the <qd_prompt>,<qd_buttons>, <qd_onpass>, <qd_onfail> and <qd_label> options, except that if there is no <qd_onpass> and the user selects ‘Yes’ in the dialog, the current command will be executed.
For example: The following will show a dialog prompting the user about whether they want to Dequeue All messages. (This is really meant for the Master user ‘RR’ to double check himself prior to removing all items in the queue.)
<?xml version = “1.0” encoding=”UTF-8″ standalone=”yes”?>
<VFPData>
<qcursor>
<qd_cmd>SENDMSG
<qd_userid>RR</qd_userid>
<qd_buttons>YN</qd_buttons>
<qd_prompt>Really DeQueue all messages?</qd_prompt>
<qd_onpass>doit</qd_onpass>
<qd_onfail>cancelit</qd_onfail>
</qcursor>
<qcursor>
<qd_label>DOIT</qd_label>
<qd_cmd>DEQUEUE</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_item>ALL</qd_item>
</qcursor>
<qcursor>
<qd_label>cancelit</qd_label>
<qd_cmd>SENDMSG</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_buttons>o</qd_buttons>
<qd_prompt>Dequeue cancelled.</qd_prompt>
</qcursor>
</VFPData>
Force Logouts
<qd_cmd> This requires the exact string ‘SHUTDOWN’ (not including the quotes).
<qd_userid> Specify the initials of the account of the person that will be logged out. The initials are listed in the Bar|Scan User table.
Optional:
<qd_prompt> Specify the message that you want to send prior to execution of this command. Like all commands, an optional message can be sent before execution of the command. The message follows the syntax, properties and requirements of the SHOWMSG command for the <qd_prompt>,<qd_buttons>, <qd_onpass>, <qd_onfail> and <qd_label> options, except that if there is no <qd_onpass> and the user selects ‘Yes’ in the dialog, the current command will be executed.
For example: The following will show a dialog with an ‘Ok’ button telling user ‘MAS’ that they are being logged out by the Administrator.
<?xml version = “1.0” encoding=”UTF-8″ standalone=”yes”?>
<VFPData>
<qcursor>
<qd_cmd>SHUTDOWN</qd_cmd>
<qd_userid>MAS</qd_userid>
<qd_buttons>O</qd_buttons>
<qd_prompt>You are begin forced to log out by the administrator for administrative purposes.</qd_prompt>
</qcursor>
</VFPData>
Import
<qd_cmd> This requires the exact string ‘IMPORT’ (not including the quotes).
<qd_userid> Specify the initials of the account in which the import will be done. The initials are listed in the Bar|Scan User table.
<qd_dbc> Specify the fully qualified path of the company file into which to do the import. This always has extension ‘dbc’.
<qd_item> Specify the name of the Formatted Import to perform. The list of Imports is set up by the user prior to its execution. It can be found in the menu item File/Import/Formatted Data. To avoid any confusion make sure that it’s name is unique.
Optional:
<qd_prompt> Specify the message that you want to send prior to execution of this command. Like all commands, an optional message can be sent before execution of the command. The message follows the syntax, properties and requirements of the SHOWMSG command for the <qd_prompt>,<qd_buttons>, <qd_onpass>, <qd_onfail> and <qd_label> options, except that if there is no <qd_onpass> and the user selects ‘Yes’ in the dialog, the current command will be executed.
Normally an import does not have a dialog box prompt, because it is performed on a timed unattended basis. See timing options below. Normally a message is sent to a specific account using the ‘P’ option. This option sends a noninteruptive message to the indicated user so they can keep track of the status of the import. See the example below.
<qd_when> Specify the date and time of when this command should be done for the first time. This is in a special xml format, with the date first, then the time. Use the following format. Pad with leading zeroes if needed.
yyyy-mm-ddThh:MM:ss
where yyyy = year
mm = month
dd = day
hh = hour (24 hour format)
MM = minutes
ss = secondse.g. January 1, 2020 at 4:15 pm is 2020-01-01T16:15:00
<qd_everyn> Specify a number for the <qd_everyu> field and one of the <qd_everyu> following values for the <qd_everyu> field:
Year, month, week, day, hour, minute
<qd_everyu> is paired with the <qd_everyn> field to specify a repetition of this command on a regularly timed basis. <qd_everyn> is a numeric value and <qd_everyu> gives the unit for counting.
E.g. <qd_everyn>1< /qd_everyn>
<qd_everyu>day</qd_everyu>This will repeat the import command once a day at the time specified by the <qd_when> field.
<qd_until> Specify the date and time of when this command should no longer be executed. This must be in the very first command. It is in a special xml format, with the date first, then the time. Use the following format. Pad with leading zeroes if needed.
yyyy-mm-ddThh:MM:ss
where yyyy = year
mm = month
dd = day hh = hour (24 hour format)
MM = minutes
ss = secondse.g. February 1, 2020 at 8:00 am is 2020-02-01T08:00:00
For example: The following will execute the formatted import named “LOCATIONS”, sending a non-interactive message to user ‘RR’ letting them know the status of the import. It does this every night at 2 am starting September 20, 2020. If the import fails it will issue an error message to the same user. If it succeeds it will do the next import and finally send a message to ‘RR’ that the import succeeded. When October 1st appears, it will automatically be dequeued and no longer execute.
Note that the first record specifies the <qd_until> value.
<?xml version = “1.0” encoding=”UTF-8″ standalone=”yes”?>
<VFPData>
<qcursor>
<qd_label>IMPORT_LO</qd_label>
<qd_cmd>IMPORT</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_buttons>P</qd_buttons>
<qd_prompt>Importing Locations.</qd_prompt>
<qd_when>2020-09-20T02:00:00</qd_when>
<qd_until>2020-10-01T00:00:00</qd_until>
<qd_everyn>1</qd_everyn>
<qd_everyu>day</qd_everyu>
<qd_onpass>IMPORT_ST</qd_onpass>
<qd_onfail>ITFAILED</qd_onfail>
<qd_dbc>appserver01SampleCompany.DBC</qd_dbc>
<qd_item>LOCATIONS</qd_item>
</qcursor>
<qcursor>
<qd_label>IMPORT_ST</qd_label>
<qd_cmd>IMPORT</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_buttons>P</qd_buttons>
<qd_prompt>Importing Statuses.</qd_prompt>
<qd_onpass>IMPORT_ORG</qd_onpass>
<qd_onfail>ITFAILED</qd_onfail>
<qd_dbc>appserver01sampleCompany.DBC</qd_dbc>
<qd_item>STATUS</qd_item>
</qcursor>
<qcursor>
<qd_label>IMPORT_ORG</qd_label>
<qd_cmd>IMPORT</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_buttons>P</qd_buttons>
<qd_prompt>Importing Organizations.</qd_prompt>
<qd_onpass>IMPORT_TR</qd_onpass>
<qd_onfail>ITFAILED</qd_onfail>
<qd_dbc>appserver01SampleCompany.DBC</qd_dbc>
<qd_item>USERS</qd_item>
</qcursor>
<qcursor>
<qd_label>IMPORT_TR</qd_label>
<qd_cmd>IMPORT</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_buttons>P</qd_buttons>
<qd_prompt>Importing Transactions.</qd_prompt>
<qd_onpass>COMPLETEDOK</qd_onpass>
<qd_onfail>ITFAILED</qd_onfail>
<qd_dbc>appserver01SampleCompany.DBC</qd_dbc>
<qd_item>TRANSACTIONS</qd_item>
</qcursor>
<qcursor>
<qd_label>COMPLETEDOK</qd_label>
<qd_cmd>SENDMSG</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_buttons>P</qd_buttons>
<qd_prompt>Import succeeded.</qd_prompt>
</qcursor>
<qcursor>
<qd_label>ITFAILED</qd_label>
<qd_cmd>SENDMSG</qd_cmd>
<qd_userid>RR</qd_userid>
<qd_buttons>P</qd_buttons>
<qd_prompt>Import failed.</qd_prompt>
</qcursor>
</VFPData>