Search code examples
powerappspowerapps-canvaspowerapps-formuladataverse

ForAll, Patching, and then Removing based on time elapsed


I'm making a canvas app using Dataverse. The app is essentially a check-in/check-out system. After a certain amount of time (12 hours), if the user has not checked themselves out, they will be forcibly removed. Whenever a visitor checks out or is removed, their "record" gets moved to the archive table.

Visitor checks in and all of their info goes to the 'Entry Point Database'. When they are checked out, they go to "Entry Point Check-outs", or the archive. It's easy enough to patch one singular visitor to the archive and delete it, but I need to have an ability to patch all "EXPIRED" entries at once.

So whenever the app starts or whenever someone interacts with a specific button, this should run:

ForAll(
    'Entry Point Databases',
    If(
        DateDiff(
            ThisRecord.'Created On',
            Now(),
            TimeUnit.Minutes
        ) / 60 > 12,
        Patch(
            'Entry Point Check-Outs',
            Defaults('Entry Point Check-Outs'),
            {
                'First Name': ThisRecord.'First Name',
                'Last Name': ThisRecord.'Last Name',
                'Company Name': ThisRecord.'Company Name',
                'Visiting Who?': ThisRecord.'Visiting Who?',
                'Check-In Time': ThisRecord.'Created On',
                'Check-Out Time': Now(),
                'Safety Brief Status': "Quizzed, Never checked out - visitation expired"
            }
        );
    )
)

Now, I need to make it so that IF it is true for that specific record, it will remove that record only. I don't want to remove all records, as some visitors may not have had 12 hours elapse since they start their visit.

My first idea was to use the Remove function, or ClearCollect instead of Patch.

Remove('Entry Point Database', ThisRecord)

OR

ClearCollect('Entry Point Check-Outs', 'Entry Point Database')

But whenever I insert either function into the IF statement, I get an error stating that those functions cannot occur within the ForAll, because they have the same source. Or it doesn't specifically apply to that record, but instead the whole table.

I would appreciate any ideas. Thank you.


Solution

  • You can use a local collection to store the intermediate list of records that should be expunged from the existing table, something like the code below:

    ClearCollect(
      ExpiredEntries,
      Filter(
        'Entry Point Databases',
        DateDiff(
          ThisRecord.'Created On',
          Now(),
          TimeUnit.Minutes
        ) / 60 > 12
      )
    );
    
    ForAll(
      ExpiredEntries,
      Patch(
        'Entry Point Check-Outs',
        Defaults('Entry Point Check-Outs'),
        {
          'First Name': ThisRecord.'First Name',
          'Last Name': ThisRecord.'Last Name',
          'Company Name': ThisRecord.'Company Name',
          'Visiting Who?': ThisRecord.'Visiting Who?',
          'Check-In Time': ThisRecord.'Created On',
          'Check-Out Time': Now(),
          'Safety Brief Status': "Quizzed, Never checked out - visitation expired"
        }
      );
      Remove('Entry Point Database', ThisRecord)
    )
    

    This way you will not be removing an entry from the data source that is used as the source for ForAll, but from a local collection instead.