Here’s my thinking. It’s untested, so TEST THOROUGHLY!!!
Assumptions:
- Payments table has a column named Amount that contains the payment amount.
- Service Availed has a column named Amount Due that contains the total amount due from the customer for the service, and Amount Paid that contains the total payment received for the service, such that Amount Due - Amount Paid = Unpaid Balance.
Because the Service Availed and Payments rows involved don’t change as a part of these computations, we should be able to use the Related Service Availeds and Related Payments virtual columns of the Service Booking table to improve efficiency and reduce complexity.
The loop condition would probably look like this:
AND(
(SUM([Related Payments][Amount]) < SUM([Related Service Availeds][Amount Due])),
(SUM([Related Payments][Amount]) > SUM([Related Service Availeds][Amount Paid]))
)
“(The sum of all payments received so far) is less than (the total amount due from all services)” (“there’s an outstanding balance”) AND “(The sum of all payments received so far) is more than (the total payments allocated per service)” (“unallocated payment remains”)
Create an action for the Service Availed table named (e.g.) Update Amount Paid of type Data: set the values of some columns in this row. Under Advanced, add an input named Available of type Decimal with a default value of 0.0. In Set these columns, set Amount Paid to this expression:
(
[Amount Paid]
+ MIN(
LIST(
[_INPUT].[Available],
([Amount Due] - [Amount Paid])
)
)
)
Within the loop, there should be an action for the Service Booking table of type Data: execute an action on a set of rows that references the Service Availed table and uses the Update Amount Paid action from above. The Referenced Rows expression would look like this:
ORDERBY(
SELECT(
[Related Service Availeds][Service Availed ID],
(([Amount Due] - [Amount Paid]) > 0.0)
),
[Service Date],
false,
[_RowNumber],
false
)
Replace Service Availed ID with the name of the key column of the Service Availed table, and Service Date with the name of the column in the Service Availed table that contains the service date. This expression gathers the related Service Availed rows that still have an unpaid balance. Note that the SELECT() expression is the same as in the loop condition earlier.
Add an input for Available with the following expression:
(SUM([Related Payments][Amount]) - SUM([Related Service Availeds][Amount Paid]))
TEST! TEST! TEST!