I’d probably handle this with a combination of a saved search and scripting.
Saved search is the easy part, create a checkbox for “invoiced” that I think you’re already hinting at and if that isn’t checked then it’s an available consultation. You could also use a script field for this which might make more sense in the long run too but a check box is nice and easy to get to in the short term. For the purposes of the script, I’m going to call this the “Consultations” form and the saved search is called “Uninvoiced Consultations”.
The next part is likely a form script that is on your invoices form. I’d expect the workflow is that you create a new invoice, select the client you’re interested in from the link from form field and then run the script. The script looks something like this:
function Import_Consultations() {
let consultations = document.getFormNamed("Consultations").getSearchName("Uninvoiced Consultations");
let invoiceClient = record.getFieldValue('fld-invoice_client_fieldId');
for (consultation of consultations) {
if (invoiceClient.getId() == consultation.getFieldValue('fld-consultation_client_fieldId').getId()) {
record.addRecordToField('fld-invoice_to_consultation_fieldId', consultation);
consultation.setFieldValue('fld-consultation_invoiced', true);
}
}
document.saveAllChanges();
}
Import_Consultations();
It’s a bit rough and untested but essentially the idea is that you’re using the saved search to find candidate records that haven’t been invoiced, that’s our first line of the function.
The list of uninvoiced consultations is going to include all of your clients because it’s a simple saved search (for ease of use), so we need to make sure we only get the client for the invoice. The second line in the function is getting the client record from the invoice record we have selected (remember this is a form script in the invoice form, so we’ll have an invoice record selected generally). The fld-invoice_client_fieldId is the field ID of the “Link from Form” field that you will have in your invoice form. If that field isn’t there, go to the “Clients” form where you’ve got the “Link to Form” with 1:M set and tick “Show inverse relationship” to create the inverse field. Once the field is available you can look below the “Description” box to get the field ID.
The third line starts the loop through all of consultations where consultation is an individual record to work with. The fourth line then implements the test to see if the record ID of the invoiceClient (this is the client record linked to the invoice from the second line of the function) matches the record ID of the client record linked to the consultation. The fld-consultation_client_fieldId is expected to be the “Link From Form” field matching that in the consultation following the same pattern as we did with the invoice.
The next line attempts to add the consultation record to the current record’s fld-invoice_to_consultation_fieldId. This should be the field ID of the Link to Form field in the Invoice to the Consultations form.
The final line in the if statement toggles the checkbox referred to as fld-consultation_invoiced in the consultation record (again, replace with the field ID of the actual checkbox) and then as we work down through the rest of the script document.saveAllChanges() tells Tap Forms that we made changes it needs to save and the final line Import_Consultations() runs the script.
Now the script is going to be fragile to bad data so I’m going to make two slight changes to it that should make it a little less fragile, here’s the updated script:
function Import_Consultations() {
let consultations = document.getFormNamed("Consultations").getSearchName("Uninvoiced Consultations");
let invoiceClient = record.getFieldValue('fld-invoice_client_fieldId');
if (!invoiceClient) {
console.log('Client is not set for invoice.');
return;
}
for (consultation of consultations) {
let consultationClient = consultation.getFieldValue('fld-consultation_client_fieldId')
if (!consultationClient) {
console.log("WARNING: Consultation is missing client: " + consultation.getUrl());
continue;
}
if (invoiceClient.getId() == consultationClient.getId()) {
record.addRecordToField('fld-invoice_to_consultation_fieldId', consultation);
consultation.setFieldValue('fld-consultation_invoiced', true);
}
}
document.saveAllChanges();
}
Import_Consultations();
The first change is to check to see if invoiceClient is set and exits the script if it isn’t. Obviously if the client isn’t set then we can’t find the matching consultations. The second is to check on the consultation and flag a warning if the client isn’t set on it. When it logs, it logs the link to the record so if you run this outside of the script editor with the console open, you can click on the link to find the record.
Disclaimer: I haven’t tested any of this, just wrote it off the top of my head and it might have errors or changes but it should give you a general idea of how to approach the problem from the scripting perspective to help automate some of the action for you.