I’ll walk through this a little as this is my bulk scan script. It’s probably a bit much but it has a bunch of piece that might help.
document.getFormNamed('Script Manager').runScriptNamed('Prompter Functions');
This is pulling in my Prompter Functions via the Script Manager method. Basically Script Manager is a Tap Forms form named ‘Script Manager’ and then it uses ‘Form Scripts’.
var tracking_number_id = 'fld-c487390743c947969cbe661cff596855';
var received_date_id = 'fld-e3e3539ee04f4cc7971c7098c572104d';
var confirmed_id = 'fld-2adb9ba8cdd048bbbb614d46b415ada5';
var alternate_tracking_numbers_id = 'fld-cf8718051bea4cc2aba0069ae76f32b7';
var alternate_tracking_number_id = 'fld-7342203d8f36415191bf8419fb6f70dc';
var carrier_id = 'fld-0950c430cb0c41f79c51d43a544b366b';
var zip_code_id = 'fld-4f73faa8937446a0a3b24e6dd4624d6b';
var shipper_id = 'fld-1789ae45fd1f4f588294eff0c2fb6045';
These are all of the field ID’s I care about, you’ll see them spliced through. Obviously your fields will be different.
function findRecord(targetTrackingNumber)
{
var targetRecord = null;
MainLoop:
for(candidateRecord of form.getRecords())
{
if (targetTrackingNumber == candidateRecord.getFieldValue(tracking_number_id))
{
targetRecord = candidateRecord;
break MainLoop;
}
for (alternateRecord of candidateRecord.getFieldValue(alternate_tracking_numbers_id))
{
if (targetTrackingNumber == alternateRecord.getFieldValue(alternate_tracking_number_id))
{
targetRecord = candidateRecord;
break MainLoop;
}
}
}
return targetRecord;
}
This is a quick method to basically brute force scan all of the records and search for them. I mentioned earlier that Brendan is adding a function to make this a little less relevant however what it’s doing is getting a list of all of the records, checking if the tracking number matches (in your case it’ll be your box barcode or item barcode) and it also checks the values of a table field that is in my shipments form. Because there are two levels of loops in this, I use a trick to make sure I break out of them easily. Shipping is fun where a package might have more than one tracking number, hence the crazy setup.
async function start(){
try {
while (1)
{
This is the start of the meat and it has three things to be interested in. The async
keyword is required to get my prompter functions to work properly and enable you to do blocking calls without having to manage the callbacks all yourself. The try
is a fallback for an exceptions that might escape and the while (1)
is our infinite loop.
let zipcode = undefined;
let carrier = '';
let barcode = '';
let scanBarcode = await promptText("Scan Shipment", "Barcode:");
This sets up some variables, in my case I’m tracking zipcode
for the package (USPS embed this into their tracking number), a carrier
that I can automatically infer (USPS and UPS) and then obviously the core barcode. This uses the promptText
function which is in that Prompter Functions I mentioned earlier. It has await
prefixed to make it block until we get a response back.
if (!scanBarcode)
{
break;
}
This is pretty straight forward, if we don’t get anything back from the barcode then we abort the loop. This is our exit criteria.
let matches = scanBarcode.match(/420(9[0-9]{4})(.*)/);
if (matches)
{
carrier = 'USPS';
zipcode = matches[1];
barcode = matches[2];
}
else
{
barcode = scanBarcode;
}
This isn’t relevant to you as much but it basically looks for a USPS barcode and extracts the useful information out of it. It resets the barcode to be what the label and tracking number actually is versus the full details that are encoded into the barcode. I’m in California so my zipcode is prefixed with a 9 which is why it looks the way it does.
matches = scanBarcode.match(/^1Z/);
if (matches)
{
carrier = 'UPS';
}
This also isn’t as relevant but it looks for a UPS style barcode and sets it automatically. Depending on how your barcode generation is done, this might be something you can apply where you have different barcode prefixes for stuff (or not).
console.log(barcode);
let targetRecord = findRecord(barcode);
I logged the barcode because I wanted to see what it was in the console. This is useful for understanding when something weird happens. This is then fed into that findRecord
method before to find a record that matches, or not.
if (targetRecord)
{
// Flip confirmed flag but otherwise leave it alone.
targetRecord.setFieldValue(confirmed_id, true);
document.saveAllChanges();
console.log("Updated existing record for " + barcode);
}
For me I’m looking to confirm or create a record that I’m scanning. In this case if for some reason the shipping number already exists and I found a matching record, I just toggle a flag saying that I know it exists and move on.
else
{
let payload = {
[tracking_number_id]: barcode,
[confirmed_id]: true
};
Ok, the else case means this tracking number doesn’t exist already so we need to create it. I start to create a new record here. This syntax with the square brackets is to get the value of tracking_number_id
instead of using tracking_number_id
as the key.
if (carrier)
{
payload[carrier_id] = carrier;
payload[zip_code_id] = zipcode;
}
If there is a carrier set then this gets set up as well including the zipcode (USPS).
let shipper = await promptText("Enter Shipper Name", "Shipper: ");
console.log(shipper);
if (shipper)
{
payload[shipper_id] = shipper;
}
I ask for the shipper name in case that’s obvious, again with the promptText
method. That’s useful for knowing where something is from if I want to add it in.
console.log(JSON.stringify(payload));
let newRecord = form.addNewRecord();
newRecord.setFieldValues(payload);
document.saveAllChanges();
I log out what I’m about to create to see what it is during debugging. I then create a new record, use setFieldValues
to set up the values and then save the changes. Too easy!
}
}
} catch (error) {
console.log("Error: " + error);
}
}
start();
This is closing everything out and then triggering the script to begin with. The catch
is the follow up to the try and is a fail safe to log the message and go from there. It’s closing out the loop so assuming you enter in a valid barcode, it’ll keep looping until it’s done.
I thought I had another script that handled a little closer to what you were doing but I can’t find where I put it.
Here’s the script in full:
document.getFormNamed('Script Manager').runScriptNamed('Prompter Functions');
var tracking_number_id = 'fld-c487390743c947969cbe661cff596855';
var received_date_id = 'fld-e3e3539ee04f4cc7971c7098c572104d';
var confirmed_id = 'fld-2adb9ba8cdd048bbbb614d46b415ada5';
var alternate_tracking_numbers_id = 'fld-cf8718051bea4cc2aba0069ae76f32b7';
var alternate_tracking_number_id = 'fld-7342203d8f36415191bf8419fb6f70dc';
var carrier_id = 'fld-0950c430cb0c41f79c51d43a544b366b';
var zip_code_id = 'fld-4f73faa8937446a0a3b24e6dd4624d6b';
var shipper_id = 'fld-1789ae45fd1f4f588294eff0c2fb6045';
function findRecord(targetTrackingNumber)
{
var targetRecord = null;
MainLoop:
for(candidateRecord of form.getRecords())
{
if (targetTrackingNumber == candidateRecord.getFieldValue(tracking_number_id))
{
targetRecord = candidateRecord;
break MainLoop;
}
for (alternateRecord of candidateRecord.getFieldValue(alternate_tracking_numbers_id))
{
if (targetTrackingNumber == alternateRecord.getFieldValue(alternate_tracking_number_id))
{
targetRecord = candidateRecord;
break MainLoop;
}
}
}
return targetRecord;
}
async function start(){
try {
while (1)
{
let zipcode = undefined;
let carrier = '';
let barcode = '';
let scanBarcode = await promptText("Scan Shipment", "Barcode:");
if (!scanBarcode)
{
break;
}
let matches = scanBarcode.match(/420(9[0-9]{4})(.*)/);
if (matches)
{
carrier = 'USPS';
zipcode = matches[1];
barcode = matches[2];
}
else
{
barcode = scanBarcode;
}
matches = scanBarcode.match(/^1Z/);
if (matches)
{
carrier = 'UPS';
}
console.log(barcode);
let targetRecord = findRecord(barcode);
if (targetRecord)
{
// Flip confirmed flag but otherwise leave it alone.
targetRecord.setFieldValue(confirmed_id, true);
document.saveAllChanges();
console.log("Updated existing record for " + barcode);
}
else
{
let payload = {
[tracking_number_id]: barcode,
[confirmed_id]: true
};
if (carrier)
{
payload[carrier_id] = carrier;
payload[zip_code_id] = zipcode;
}
let shipper = await promptText("Enter Shipper Name", "Shipper: ");
console.log(shipper);
if (shipper)
{
payload[shipper_id] = shipper;
}
console.log(JSON.stringify(payload));
let newRecord = form.addNewRecord();
newRecord.setFieldValues(payload);
document.saveAllChanges();
}
}
} catch (error) {
console.log("Error: " + error);
}
}
start();