OMS Pro: Decoding App Scripts
Before reading through this document, make sure you remember the difference between Tables, Views, Records, and Forms as outlined in "TrackVia 101". If you expect to be spending a lot of time working with App Scripts in TrackVia, it may also be helpful to bookmark the Groovy docs and TrackVia's Application Scripts docs on your work computer.
What Are App Scripts?
You may remember from the "TrackVia 101" article that behind the scenes, TrackVia is basically a bunch of spreadsheets (Tables) that store data (Records). The information in each Record is separated into different Fields (columns), and a Record in one Table can "know" a Record in another table through a special kind of Field called a Link.
App Scripts, or Application Scripts, refers to some custom Groovy* code that is saved to a Table, and that fires off when something changes on that table in order to update the data in some way. Sometimes, when troubleshooting unexpected behavior of data in TrackVia, you may find that you need to figure out how an App Script is affecting it.
What Tables Are Made Of: Data Types & Formulas
The Fields that each Table contains are created when the Table is created, but can be changed as needed. To see the Fields in a Table, you can look at the Default View and read them where they're listed along the top of the page, or you can select "Edit Table" from the hamburger menu at the top right of any View within that Table. This will take you to the Table Editor screen, like the on in the below screenshot from the Site Visit Table in OMS.

As you can see by the colorful bars at the left of each Included Field, as well as from the smaller text beneath each Field name, when a Field gets added to a Table, it must accept a certain kind of data. For instance, a Field that's going to contain the name of a Location would probably be a "Single Line" field with a line green border on its left side. Meanwhile, the cost of a Part would probably be a Number field with a cyan left border.
In the world of computer programming, different types of data like this are also distinct from each other. For instance, a single line of text is commonly referred to as a string and will be surrounded in "quotes" when typed in a line of code. This prevents the computer from splitting the characters up and tells it to treat them as a string, or a sentence. Another type of data is a boolean, which means a value that can only be true or false.
The way numbers are treated in coding language can be a little extensive, but the most important thing to know for OMS is that a number with up to two decimal places (like currency) is known in Groovy as a float, a number with more decimal places than that is a double, and a number with no decimal places is called int, short for integer. If you find other low-level data types declared in an App Script, you can look them up here in the Groovy docs. You can also, frankly, just Google "groovy" and the data type in question, and expect to find the answer pretty quickly. Once you know the basics of coding languages, the rest is mostly troubleshooting and Googling!
You'll also notice some more complicated Field types in the screenshot above, like the Payment Link Field, which is a "Calculated Text" Field. If you click on it, you'll see this appear in the panel on the right of your screen.

This is an example of a TrackVia formula (see the docs on those here - this page will also pop open if you click "Get help on formulas" as shown in the screenshot above) which does share similarities with Groovy and other coding languages, but... isn't. The syntax of a TrackVia formula is defined by TrackVia, so you'll want to decode those using their docs.
In this case, the formula is creating a string (single line of text) which will be recognizable to anyone viewing the Record as a URL. If the "Send Payment Link" field is not blank, it will fill the Payment Link field with a string that starts with "https://data.locdocinc.com/payment/", then multiplies the number in the Grand Total field by 100 and rounds up to the next whole number (ceiling) - note that this basically just means removing the decimal place from a dollar amount - then types "/", then the value in the Ticket Number Field, then "/sv_" followed by the value in the API_ID field, followed by "/". If the "Send Payment Link" is blank, it will instead display "Not Ready". By looking at this formula, you can surmise that any time you need a payment link for a Site Visit, you can guess what the URL will be yourself by following this same logic. For example, for site visit #12345, if the customer needs to pay Loc-Doc $99.99, you can surmise that the correct payment link will be "https://data.locdocinc.com/payment/9999/12345/sv_"(whatever API_ID is). If you were paying attention to the TrackVia 101 SOP, you might remember that you can see every value a record has by switching to the Default Form, or by side-scrolling long enough while looking at that Record in the Default View. And that's it! Now you know how to generate a custom payment link with only three pieces of information, all because you took the time to understand the formula in a Calculated Field!
So... What's An App Script?
With all these great types of Fields, what else could Tables possibly be doing with our data? Sometimes, the work that needs to be automated to make the data work better for our purposes is too complicated for a formula in a Calculated Field, and isn't something we'd want a user to have to deal with. In those cases, we use App Scripts.
You can see the App Scripts on any Table by clicking the green "Application Scripts" link at the top of the Table Editor page. This sends you to a page that looks something like this:

Note the column on the left. There are four different times an App Script could run:
Before Insert: the moment before a new Record is created
After Insert: the moment after a new Record is created
Before Update: the moment before an existing Record is updated
After Update: the moment after an existing Record is updated
Each of these four possible "trigger events" will be able to take different scripts, so if you're trying to solve a particular problem, make sure to skim all of the scripts associated with each trigger!
As mentioned earlier, TrackVia only understands app scripts that are written in a specific coding language called Apache Groovy, or Groovy for short. If you come across something in an app script that you can't understand, googling very well may lead you to your answer! If it doesn't, the answer should be somewhere in the Groovy docs or in TrackVia's Application Scripts docs.
A Very Groovy Overview
How The Record's Data Gets Pulled Into The App Script
We already learned that Groovy, like TrackVia and like most programming languages, classifies all data into simple data types: strings for words or phrases, ints for whole numbers, floats for numbers with two decimal places, and doubles for numbers with more decimal places than two. Groovy, like any coding language, expects you to give a specific instance of data a "name", and to refer to it by that name when you are working with it. This is called declaring a variable. You may remember concepts like this from algebra classes in school, when "x" would be used to represent a certain number. So in Groovy, if you want to refer to the name of a Location (a string) repeatedly within your code, you would start off by saying something like:
String loc = '4301 Stuart Andrew Boulevard' as String;At any other point in your code, then, you could type loc to refer to "4301 Stuart Andrew Boulevard".
Other than the simple data types described above, the most important Groovy variable to know about for working in TrackVia is a map. If you know other programming languages, you may recognize this as an object or a dictionary. A map is officially defined as "a collection of key-value pairs", but can more unofficially be described as a computer-y way to think of a Record.
A Record, like a row in a spreadsheet, is a bunch of predefined categories (Fields in TrackVia) which are filled in with some information. For instance, a Location Record might have Fields for a Street Address, Company Name, and Zip Code. Those field names are "keys" by which you might be able to refer to the information ("what's the Company Name on that Record?"), and the data in the field is the "value". So, a TrackVia Record looks like this when it is assigned to a Groovy variable as a map:
Map locdoc = ['Street Address' : '4301 Stuart Andrew Blvd', 'Company Name' : 'Loc-Doc Security', 'Zip Code' : '28217'] as Map;And if you wanted to quickly refer to just the Company Name Field later, you could refer to it as:
locdoc['Company Name'];...which would have a value of 'Loc-Doc Security' (which is a string).
At any time in an app script, you can access the Record that is being created or updated (the Record on which the script is running) by using a built-in map variable called currentValues. On updates specifically, you can also access a map called previousValues. This means that, if someone were to try to update an existing Record like the locdoc mapped above to put in a silly fake address, the person writing the app script could access the original address from before the Record was updated by typing:
previousValues['Company Name'];
Understanding TrackVia's Prewritten Shortcuts
Once you have the data you want to work with assigned to a variable, you can make changes to it using pre-written chunks of code by TrackVia called functions. A function just means a set of instructions that were written in a programming language and then assigned to a variable, which you can use to run them on your data. For example, a very common function you'll see in the app scripts is "loadRecord()". If you see something like this...
Map taskName = loadRecord("Site Visit Tasks", "Task Name", "Trip Charge") as Map;...you can reference where the TrackVia docs (linked above, and again here) define the function "loadRecord()" to see that in order to return the Record you need, the function must to be given a Table, Field, and Value to point it to the correct Record you want it to load. In this case, it looks into the Site Visit Tasks Table for a Record with the value "Trip Charge" in the Field called "Task Name", and it loads that Record into the variable taskName. From this point forward, whenever you see taskName in the code, you know that it's referring to this specific existing Record. If you then needed to access the value that that Record has in its "Estimated Completion Time (Minutes)" Field, you could bring that into your code by typing:
taskName['Estimated Completion Time (Minutes)'];App Scripts That Only Run In Certain Conditions
It is also important to understand conditionals, commonly referred to as if statements or if/else statements. For Groovy's specific if/else syntax, check out their docs here.
The main thing an app script will want to tell TrackVia is to do something to the data if it meets a certain condition. For example, the code in the screenshot of the Site Visit Table above:

When the computer reads these lines, it reads, "If there is currently nothing in the Field called "Link to Location/Facility", I should throw an error at the user that says "You must select a Location", and "If there is currently nothing in the Field called Link to Customers, I should throw the user an error that says "You must select a Customer". For Groovy, if/else syntax is written:
if(something that might be true) {
things to do if that something is true;
} else{
things to do if that something isn't true;
};And since the conditional scripts in the screenshot above are written on the "Before Insert" tab, you can surmise that a new Record can't be added to the Site Visit table if its "Link to Location/Facility" or "Link to Customers" Fields are empty.
Parsing an app script that isn't familiar to you may take a bit of time, but it is essential to understand how information that is put into a TrackVia Table is handled, and, in many cases, to understand how different Tables may be working together "behind the scenes" when there isn't an obvious "Link To ___ Table" Field present. Just remember to be patient, to keep the docs handy, and to word your Google searches carefully when you come across something unfamiliar!
*Groovy is the name of the coding language TrackVia knows how to read, not an adjective describing how I or anyone on earth feels about this ancient Java-based language.