Is something like this even possible using C# in a customization, or maybe with App Studio timers? I haven’t started writing anything yet because I’m not sure of the best direction, so any guidance or examples would be hugely appreciated.
I’m not a C# / Code guy… but I think you could pull this off via App Studio events if you wanted to.
That being said, the provided App Studio “timer” event action is, I think, just a delay timer (counts down), not a running clock (counts up).
My first thought on an approach would be just to grab Constant.CurrentTime at specific events and then calculate the difference between captures:
Constant.CurrentTime is number of seconds since midnight. So, if you subtract one time from another, you should be left with how many seconds in between those two events. I would store those delta values where ever you’re recording these… assuming you have UD Fields set up for that so you can store and review them later?
~*~
EDIT!!! - THIS APPROACH DOES NOT WORK! The event flow does… but using Constant.CurrentTime is a no-go!!!
See later posts for better approach.
~*~
For example:
First Event, I would set the trigger to after onClick_ToolNew (or whatever is triggering you creating a new record). The only thing you need in this event would be a row update to capture the current time stamp. For example, TransView.StartSalesTime = "{Constant.CurrentTime}"
A potential hiccup I see is that checkboxes can be inadvertently checked/unchecked, etc. So, you would need a condition in those onblur events to only record the next time stamp when the checkbox value = true. So…
Second Event is triggered by your first Section Complete checkbox. You’d need a condition for checkbox value = true, if true, set TransView.EndSalesTime = "{Constant.CurrentTime}"… then you could use a calculation widget to find the difference (TransView.EndSalesTime - TransView.StartSalesTime). Store the value from that calculation widget into your longterm storage column.
If someone unchecks the box [checkbox value = false], no problem, your condition will stop a new time stamp from being recorded. If they re-check the box, it will overwrite the end time with an updated time stamp, calculate a new difference in seconds, and update your final stored value.
For the next event, you could just use the EndSalesTime as the base line for your next phase… again, subtract it from the onblur of your next section completion checkbox (Commercial, etc.). Store that delta value for later.
wash, rinse, repeat for as many sections as you need.
At the end, you would just include another calculation widget that sums all your individual stored section values and that gives you an overall time spent.
So, if you wanted to try using events, I think you would just need one event when you create a new record (to grab the initial CurrentTime) and then an event onblur of each of your completion checkboxes. Then its just math.
I agree with this approach — it’s a smart, pragmatic way to do it without dropping straight into C#.
Using Constant.CurrentTime with event-based captures is exactly how I’d think about it in App Studio as well. You’re effectively turning key user actions into checkpoints, and once you have consistent timestamps, the rest is just math. From a tracking and reporting perspective, that’s far cleaner than trying to infer time later.
That said, if App Studio isn’t a strong skillset for the team (or if this starts getting complex), this logic could translate very naturally into a BPM as well. A pre-processing BPM on BO.Method: SalesOrder.GetNewOrderHed (or even specific update methods) would be a good starting point to:
Capture the initial timestamp centrally
Enforce consistency regardless of UI customization
Reduce reliance on client-side behavior
You could still use App Studio for the UX and checkpoints, but let BPM handle the persistence and validation if needed.
Do as little as possible in application studio and as much as possible in functions & BPM’s
Application studio is horribly buggy and a nightmare to work in
The client can never be trusted.
If you count on the UI to track how long it takes, a savvy person could use browser tools to edit the time. And a non-savvy person could have AI help them do it.
Also - it seems like {Constant.CurrentTime} is setting the same seconds after midnight on both events, and it doesn’t matter how long I wait before checking section complete box.
From what I can tell, the “Constant” dataview is just a snapshot in time when the app starts. It populates the Constant dataview and the values there don’t change.
So… Constant.CurrentTime won’t work for this.
Try this approach… use Date.now()
Date.now() is milliseconds since 1/1/1970 (Unix Epoch), so going this route, you don’t really need to care what day it is. You could come back days later and click your next trigger and the end time will just be another numeric value.
EndTime - StartTime will result in a bunch of milliseconds… divide those by 1,000 to get seconds. Or do additional maths to get minutes/hours/days… whatevs.
I know its because of the event after GetNew trigger, as it works fine if i disable the event, but if i change it to after onClick_toolSave it will reset the time every time someone saves it?
I also tried changing the trigger to event after onClick_toolNew but it didn’t fire at all.
Here are all the events that fire when i click add new.
Managed to resolve this using the event AfterUpdate trigger and adding a condition that checks if the field is equal to “0”, if it is do the row-update, otherwise don’t.
So on first save it will add the time, then the condition will prevent the timer resetting each time someone saves the record after this.