The whole stack is bound to be slow and tricky because everything is heavily dependent on summaries and other calcs that cannot be stored. However, at the very least you'll need to address the following:
• lines::total and lines::total_taxable are summary fields, so to access their data in your jobs::total_grandand jobs::total_tax calcs you need to use GetSummary().
Give some though to removing the unstored calcs and replacing calcs such as Invoice Grand Total with a stored number field which is set via a script trigger when the invoice record is committed. Then there is no latent update time when viewing the grand total of the invoice, or when searching invoices by total.
It can take a while to adapt to not using unstored calcs, but the performance is worth the change. One can use the Evaluate function to update a stored number based on edited fields in the same table, removing the need for unstored calcs among a record's own fields, and then use script triggers onRecordCommit to update totals in related tables, especially when editing Invoice line items via a portal and updating tax and totals on the invoice.
This can speed up things like sales reports by as much as 10x to 100x over a networked system. Also removes all the refresh issues you described.
Thanks for the suggestions. I went ahead and changed the total_grand and total_tax fields to use the GetSummary function.
Stephen, can you clarify a little more for me? Are you saying that total_grand shouldn't be a calculation at all, just a number field that calculates using the on record commit script trigger?
Yes, use the same calculation, but instead of making the field itself a calc field, make it a number field with an auto-enter calculation. The benefit of this approach is speed—once the value is set it can be indexed, and doesn't need to be altered unless the values it references are changed, in which case you use a script trigger to update it.