cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Anonymous
Not applicable

Building a Timeclock App

I am in the process of building a Timeclock App that will allow my employees to punch-in and punch-out for shift start/end and also lunch breaks. I am just not so sure on how get the punches on the same record. And also for days where maybe they work a half day when they punch-out, for the app to know it's not a lunch punch-out.

 

Is there any app samples already out there or anyone know a good place to start?

 

Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions

@Anonymous 

So, I have a fairly quick solution for you.  I could provide this as an attached App, but instead I will present it as a "build it yourself kit".  Mostly because it relies on a SharePoint list and that's always problematic with sample shareable apps, and...people love to build stuff!

 

Step 1 - Create the SharePoint List:

Create a List in SharePoint - Call it TimeTracker

Leave the Title as is but Create 3 additional columns:

   1) ActivityType - Text Column

   2) ActivityDateTime - Text Column

   3) AcitivyDate - Date Column (include Time)

 

Step 2 - Create Your App:

Call it what you want.

   1) Connect to the datasource TimeTracker

   2) Create a New Screen (a scrollable screen).  Select the Canvas1 and resize it.  (that will kill the connection to the label on that screen), then Cut the Canvas1 from the screen.  Return to the Screen1 and paste the Canvas1 there.  You can now delete Screen2.  There is an interesting reason for doing this that will soon become obvious.

 

   3) On DataCard1 Update property, place the following formula:

With({lclUser:Lower(User().Email)},
    With({lclRecs:Filter(TimeTracker, Title=lclUser && StartsWith(ActivityDateTime, Text(Today(), "yyyymmdd")))},

    {CheckIn: LookUp(lclRecs, ActivityType="CheckIn", ActivityDate),
     CheckOut: LookUp(lclRecs, ActivityType="CheckOut", ActivityDate),
     LunchOut: LookUp(lclRecs, ActivityType="LunchOut", ActivityDate),
     LunchIn: LookUp(lclRecs, ActivityType="LunchIn", ActivityDate)
    }
   )
)

 

   4) In your DataCard1, place two buttons and 4 labels.  Button1, Button2, Label1, Label2, Label3, Label4
     Set the following properties for listed controls:

 

      Label1

           Text Property:  

                  Coalesce(Text(DataCard1.Update.CheckIn, ShortDateTime), "No Check In Time")

 

      Label2

            Text Property: 

                  Coalesce(Text(DataCard1.Update.CheckOut, ShortDateTime), "No Check Out Time")

 

      Label3

            Text Property: 

                  Coalesce(Text(DataCard1.Update.LunchOut, ShortDateTime), "No Lunch Out Time")

 

      Label4

            Text Property:  

                   Coalesce(Text(DataCard1.Update.LunchIn, ShortDateTime), "No Lunch In Time")

 

      Button1

            Text Property: 

                    "Check " & If(IsBlank(DataCard1.Update.CheckIn), "In", "Out")

            Visible Property: 

                    IsBlank(DataCard1.Update.CheckOut)

            OnSelect Action: 

                    Patch(TimeTracker, Defaults(TimeTracker), {Title:Lower(User().Email), ActivityType:"Check" & If("In" in Self.Text, "In", "Out"), ActivityDateTime:Text(Now(), "yyyymmddhhmm"), ActivityDate:Now()})

 

      Button2

            Text Property: 
                       "Lunch " & If(IsBlank(DataCard1.Update.LunchOut), "Out", "In")

            Visible Property: 

                       !IsBlank(DataCard1.Update.CheckIn) && IsBlank(DataCard1.Update.LunchIn) && IsBlank(DataCard1.Update.CheckOut)

            OnSelect Action: 

                       Patch(TimeTracker, Defaults(TimeTracker), {Title:Lower(User().Email), ActivityType:"Lunch" & If("In" in Self.Text, "In", "Out"), ActivityDateTime:Text(Now(), "yyyymmddhhmm"), ActivityDate:Now()})

 

Finally, for testing ability so you can do this over and over again, put a Trash Can Icon on your screen and set the OnSelect Action to:  With({lclUser:Lower(User().Email)}, RemoveIf(TimeTracker, Title=lclUser && StartsWith(ActivityDateTime, Text(Today(), "yyyymmdd"))))

 

 

Now play your app and click away!

 

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
NOTE: My normal response times will be Mon to Fri from 1 PM to 10 PM UTC (and lots of other times too!)
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!

View solution in original post

17 REPLIES 17

@Anonymous 

This is a popular question I see on the forums and I am interested in helping.  I want to understand your specific requirements a little better first though.

 

Can you please tell me how the current employee will be determined?  Is this a punch-clock people log into on their desktop computers and every user has their own computer?   If yes, we can rely on the user login to tell us who is currently using the app.

 

What punch types do you want?

 

  • Clock-In (Start Shift)
  • Clock-Out (Lunch)
  • Clock-Out (End Shift)
  • What others?

 

---
Please click "Accept as Solution" if my post answered your question so that others may find it more quickly. If you found this post helpful consider giving it a "Thumbs Up."

Anonymous
Not applicable

@mdevaney 

 

All the users will be determined by their Office 365 login when they open the PowerApp. I have a SharePoint List that will populate when the user clicks on the appropriate button. I will have 4 buttons (Punch In, Lunch Out, Lunch In, Punch Out). So basically, they will click the button appropriate for their punch action. I am going to try and disable the buttons if that punch time has already been done.

@Anonymous 

Great, totally understand what you are saying.

 

What other information does the user need to see on the screen?  This is a question about features:

  • Current status
  • Current time elapsed in status
  • Current day-history of check-in/out
  • Undo button (undo any punch within 5 minutes of pressing the button)
  • Totals: sum of all time clocked in for the day, sum of all breaks, etc.
  • Add any other features you can think of (cool ideas welcome)

 

I'm toying with the idea of making a proof-of-concept app here and writing a blog article... so that's why I'm asking for so many ideas.  I want to make it true-to-life as possible.  With the features someone would actually need.

 

---
Please click "Accept as Solution" if my post answered your question so that others may find it more quickly. If you found this post helpful consider giving it a "Thumbs Up."

 

@Anonymous 

So, I have a fairly quick solution for you.  I could provide this as an attached App, but instead I will present it as a "build it yourself kit".  Mostly because it relies on a SharePoint list and that's always problematic with sample shareable apps, and...people love to build stuff!

 

Step 1 - Create the SharePoint List:

Create a List in SharePoint - Call it TimeTracker

Leave the Title as is but Create 3 additional columns:

   1) ActivityType - Text Column

   2) ActivityDateTime - Text Column

   3) AcitivyDate - Date Column (include Time)

 

Step 2 - Create Your App:

Call it what you want.

   1) Connect to the datasource TimeTracker

   2) Create a New Screen (a scrollable screen).  Select the Canvas1 and resize it.  (that will kill the connection to the label on that screen), then Cut the Canvas1 from the screen.  Return to the Screen1 and paste the Canvas1 there.  You can now delete Screen2.  There is an interesting reason for doing this that will soon become obvious.

 

   3) On DataCard1 Update property, place the following formula:

With({lclUser:Lower(User().Email)},
    With({lclRecs:Filter(TimeTracker, Title=lclUser && StartsWith(ActivityDateTime, Text(Today(), "yyyymmdd")))},

    {CheckIn: LookUp(lclRecs, ActivityType="CheckIn", ActivityDate),
     CheckOut: LookUp(lclRecs, ActivityType="CheckOut", ActivityDate),
     LunchOut: LookUp(lclRecs, ActivityType="LunchOut", ActivityDate),
     LunchIn: LookUp(lclRecs, ActivityType="LunchIn", ActivityDate)
    }
   )
)

 

   4) In your DataCard1, place two buttons and 4 labels.  Button1, Button2, Label1, Label2, Label3, Label4
     Set the following properties for listed controls:

 

      Label1

           Text Property:  

                  Coalesce(Text(DataCard1.Update.CheckIn, ShortDateTime), "No Check In Time")

 

      Label2

            Text Property: 

                  Coalesce(Text(DataCard1.Update.CheckOut, ShortDateTime), "No Check Out Time")

 

      Label3

            Text Property: 

                  Coalesce(Text(DataCard1.Update.LunchOut, ShortDateTime), "No Lunch Out Time")

 

      Label4

            Text Property:  

                   Coalesce(Text(DataCard1.Update.LunchIn, ShortDateTime), "No Lunch In Time")

 

      Button1

            Text Property: 

                    "Check " & If(IsBlank(DataCard1.Update.CheckIn), "In", "Out")

            Visible Property: 

                    IsBlank(DataCard1.Update.CheckOut)

            OnSelect Action: 

                    Patch(TimeTracker, Defaults(TimeTracker), {Title:Lower(User().Email), ActivityType:"Check" & If("In" in Self.Text, "In", "Out"), ActivityDateTime:Text(Now(), "yyyymmddhhmm"), ActivityDate:Now()})

 

      Button2

            Text Property: 
                       "Lunch " & If(IsBlank(DataCard1.Update.LunchOut), "Out", "In")

            Visible Property: 

                       !IsBlank(DataCard1.Update.CheckIn) && IsBlank(DataCard1.Update.LunchIn) && IsBlank(DataCard1.Update.CheckOut)

            OnSelect Action: 

                       Patch(TimeTracker, Defaults(TimeTracker), {Title:Lower(User().Email), ActivityType:"Lunch" & If("In" in Self.Text, "In", "Out"), ActivityDateTime:Text(Now(), "yyyymmddhhmm"), ActivityDate:Now()})

 

Finally, for testing ability so you can do this over and over again, put a Trash Can Icon on your screen and set the OnSelect Action to:  With({lclUser:Lower(User().Email)}, RemoveIf(TimeTracker, Title=lclUser && StartsWith(ActivityDateTime, Text(Today(), "yyyymmdd"))))

 

 

Now play your app and click away!

 

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
NOTE: My normal response times will be Mon to Fri from 1 PM to 10 PM UTC (and lots of other times too!)
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!
Anonymous
Not applicable

@mdevaney 

 

This is what I have started

 

time33.png

Anonymous
Not applicable

@RandyHayes 

 

Is there a specific reason for using a Scrollable Screen? The app doesn't really need to scroll since it will all fit on one screen nicely. Or can I remove the scrollbar?

@Anonymous 

You're actually not using a scrollable screen.  You're just borrowing a "canvas" with a datacard from one.

You can size the canvas as large as the screen and set the datacard size to suit your needs and not scroll.

 

The long story on why we use this in the app...

If you learn one thing about my PowerApps style...I can't stand variables.  As a developer, they are so much different in PowerApps.

So, I typically rely on the actual properties of a control to determine the state of things rather than try to set variables when state changes so that I can then look at the Variable someplace else...to me it's a total waste of time.  Just look at the state of the control.  If the control changes because of a change in the underlying data, then I don't need to do anything else...I already have the value because it is in the control.

One limitation is that many times I need a Record of information, not just a single value.  I have found that a DataCard in a Canvas has an update property that can be anything I want.  And, there is no apparent use for that property anywhere else.  Once I discovered that, it became my go-to place for having a dynamically changing "variable".  Because, as you see in the app sample, I do not actually create a variable for the 4 different times.  Instead they all come from that Update property. And, it will automatically change on its own when the underlying data changes...I don't have to do another variable set.  Love it!!!

 

Don't let the canvas and datacard throw you though.  I only borrowed that (and you will notice I said to cut it from a scrollable screen, but it on your main and then delete the scrollable screen).  What I realized that I mentioned was to put the controls "IN" the datacard.  You actually don't need to do that.  Your datacard can me completely empty...we are just using the Update property on that datacard as no other control offers this type of functionality. 

You could empty out your datacard and put the controls on the main screen and then even set the canvas visible to false.  No more pesky screen interference!

 

I hope that all makes sense.

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
NOTE: My normal response times will be Mon to Fri from 1 PM to 10 PM UTC (and lots of other times too!)
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!

@Anonymous 

By the way...I did a video on this concept.  Check it out!

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
NOTE: My normal response times will be Mon to Fri from 1 PM to 10 PM UTC (and lots of other times too!)
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!
Anonymous
Not applicable

@RandyHayes 

 

I am going to watch your video now. 

 

I subscribed to your YouTube page and also "Liked" the video.

Helpful resources

Announcements

Community will be READ ONLY July 16th, 5p PDT -July 22nd

Dear Community Members,   We'd like to let you know of an upcoming change to the community platform: starting July 16th, the platform will transition to a READ ONLY mode until July 22nd.   During this period, members will not be able to Kudo, Comment, or Reply to any posts.   On July 22nd, please be on the lookout for a message sent to the email address registered on your community profile. This email is crucial as it will contain your unique code and link to register for the new platform encompassing all of the communities.   What to Expect in the New Community: A more unified experience where all products, including Power Apps, Power Automate, Copilot Studio, and Power Pages, will be accessible from one community.Community Blogs that you can syndicate and link to for automatic updates. We appreciate your understanding and cooperation during this transition. Stay tuned for the exciting new features and a seamless community experience ahead!

Summer of Solutions | Week 4 Results | Winners will be posted on July 24th

We are excited to announce the Summer of Solutions Challenge!   This challenge is kicking off on Monday, June 17th and will run for (4) weeks.  The challenge is open to all Power Platform (Power Apps, Power Automate, Copilot Studio & Power Pages) community members. We invite you to participate in a quest to provide solutions in the Forums to as many questions as you can. Answers can be provided in all the communities.    Entry Period: This Challenge will consist of four weekly Entry Periods as follows (each an “Entry Period”)   - 12:00 a.m. PT on June 17, 2024 – 11:59 p.m. PT on June 23, 2024 - 12:00 a.m. PT on June 24, 2024 – 11:59 p.m. PT on June 30, 2024 - 12:00 a.m. PT on July 1, 2024 – 11:59 p.m. PT on July 7, 2024 - 12:00 a.m. PT on July 8, 2024 – 11:59 p.m. PT on July 14, 2024   Entries will be eligible for the Entry Period in which they are received and will not carryover to subsequent weekly entry periods.  You must enter into each weekly Entry Period separately.   How to Enter: We invite you to participate in a quest to provide "Accepted Solutions" to as many questions as you can. Answers can be provided in all the communities. Users must provide a solution which can be an “Accepted Solution” in the Forums in all of the communities and there are no limits to the number of “Accepted Solutions” that a member can provide for entries in this challenge, but each entry must be substantially unique and different.    Winner Selection and Prizes: At the end of each week, we will list the top ten (10) Community users which will consist of: 5 Community Members & 5 Super Users and they will advance to the final drawing. We will post each week in the News & Announcements the top 10 Solution providers.  At the end of the challenge, we will add all of the top 10 weekly names and enter them into a random drawing.  Then we will randomly select ten (10) winners (5 Community Members & 5 Super Users) from among all eligible entrants received across all weekly Entry Periods to receive the prize listed below. If a winner declines, we will draw again at random for the next winner.  A user will only be able to win once overall. If they are drawn multiple times, another user will be drawn at random.  Individuals will be contacted before the announcement with the opportunity to claim or deny the prize.  Once all of the winners have been notified, we will post in the News & Announcements of each community with the list of winners.   Each winner will receive one (1) Pass to the Power Platform Conference in Las Vegas, Sep. 18-20, 2024 ($1800 value). NOTE: Prize is for conference attendance only and any other costs such as airfare, lodging, transportation, and food are the sole responsibility of the winner. Tickets are not transferable to any other party or to next year’s event.   ** PLEASE SEE THE ATTACHED RULES for this CHALLENGE**   Week 1 Results: Congratulations to the Week 1 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge. Community MembersNumber of SolutionsSuper UsersNumber of Solutions @anandm08  23 @WarrenBelz  31 @DBO_DV  10 @Amik  19 AmínAA 6 @mmbr1606  12 @rzuber  4 @happyume  7 @Giraldoj  3@ANB 6 (tie)   @SpongYe  6 (tie)     Week 2 Results: Congratulations to the Week 2 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge. Community MembersSolutionsSuper UsersSolutions @anandm08  10@WarrenBelz 25 @DBO_DV  6@mmbr1606 14 @AmínAA 4 @Amik  12 @royg  3 @ANB  10 @AllanDeCastro  2 @SunilPashikanti  5 @Michaelfp  2 @FLMike  5 @eduardo_izzo  2   Meekou 2   @rzuber  2   @Velegandla  2     @PowerPlatform-P  2   @Micaiah  2     Week 3 Results: Congratulations to the Week 3 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge.   Week 3:Community MembersSolutionsSuper UsersSolutionsPower Apps anandm0861WarrenBelz86DBO_DV25Amik66Michaelfp13mmbr160647Giraldoj13FLMike31AmínAA13SpongYe27     Week 4 Results: Congratulations to the Week 4 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge.   Week 4:Community MembersSolutionsSuper UsersSolutionsPower Apps DBO-DV21WarranBelz26Giraldoj7mmbr160618Muzammmil_0695067Amik14samfawzi_acml6FLMike12tzuber6ANB8   SunilPashikanti8

Check Out | 2024 Release Wave 2 Plans for Microsoft Dynamics 365 and Microsoft Power Platform

On July 16, 2024, we published the 2024 release wave 2 plans for Microsoft Dynamics 365 and Microsoft Power Platform. These plans are a compilation of the new capabilities planned to be released between October 2024 to March 2025. This release introduces a wealth of new features designed to enhance customer understanding and improve overall user experience, showcasing our dedication to driving digital transformation for our customers and partners.    The upcoming wave is centered around utilizing advanced AI and Microsoft Copilot technologies to enhance user productivity and streamline operations across diverse business applications. These enhancements include intelligent automation, AI-powered insights, and immersive user experiences that are designed to break down barriers between data, insights, and individuals. Watch a summary of the release highlights.    Discover the latest features that empower organizations to operate more efficiently and adaptively. From AI-driven sales insights and customer service enhancements to predictive analytics in supply chain management and autonomous financial processes, the new capabilities enable businesses to proactively address challenges and capitalize on opportunities.    

Updates to Transitions in the Power Platform Communities

We're embarking on a journey to enhance your experience by transitioning to a new community platform. Our team has been diligently working to create a fresh community site, leveraging the very Dynamics 365 and Power Platform tools our community advocates for.  We started this journey with transitioning Copilot Studio forums and blogs in June. The move marks the beginning of a new chapter, and we're eager for you to be a part of it. The rest of the Power Platform product sites will be moving over this summer.   Stay tuned for more updates as we get closer to the launch. We can't wait to welcome you to our new community space, designed with you in mind. Let's connect, learn, and grow together.   Here's to new beginnings and endless possibilities!   If you have any questions, observations or concerns throughout this process please go to https://aka.ms/PPCommSupport.   To stay up to date on the latest details of this migration and other important Community updates subscribe to our News and Announcements forums: Copilot Studio, Power Apps, Power Automate, Power Pages

Users online (853)