Results 1 to 5 of 5

Thread: Factory TimeClock App in Lianja 9.5

  1. #1
    Lianja Development Team barrymavin's Avatar
    Join Date
    Feb 2012
    Location
    UK, USA, Thailand
    Posts
    7,165
    Blog Entries
    22

    Factory TimeClock App in Lianja 9.5

    In Lianja 9.5 I have completed the example_timeclock App that is provided with the Lianja App Builder.

    This is now a fully functional "Factory Time Clock" App for employees to clock in, clock out and manage the clock and employees.

    It is created as a "standalone" Lianja App and can be installed on any machine without Lianja Runtime being present.

    You can study this small App to see how to build standalone desktop Apps in Lianja.

    You login as "admin" to be able to manage the clock and the employees.

    You login as "user" to leave the timeclock app open for employees to login.

    The "setup.prg" in the example_timeclock App can be customized. If required you can set datadir to a network drive on a LAN to share data across multiple time clocks. e.g

    Code:
    set datadir to f:\data\
    The "parameters" property in example_timeclock.prg can also be used to customize the "login" form.

    I intend at a later date to add face recognition into this App using python opencv. LianjaScript and Python are closely integrated so you can use all the Python modules for AI and image manipulation.

    Details can be found at:
    https://medium.com/@gowtham180502/ho...n-61d8d953a942

    Feel free to enhance this App for your specific needs.

    For anyone interested this is the source code that you can read and study:

    File: setup.prg

    Code:
    // this is called when the app runs to setup databases, tables etc.
    if not Lianja.standalone
        return
    endif
    
    set debugout on
    debugout "running setup.prg"
    debugout "filepath: "+Lianja.standalonefilepath
    
    if not databaseExists("factory")
        debugout "database factory does not exist"
        create database factory
        try
            open database factory
            create table employees (badgeno char(30), firstname char(30), lastname char(30), photo blob)
            insert into employees (badgeno, firstname, lastname) values ("A1234", "John", "Doe")
            create table timeclock (badgeno char(30), clockin datetime, clockout datetime, clockinphoto blob, clockoutphoto blob)
        catch
            debugout "An error occurred"
        endtry
    endif
    
    close database 
    
    debugout "setup completed successfully"
    File: example_timeclock.prg

    Code:
    //
    // example_timeclock App
    //
    // When this app runs as a standalone app the setup.prg script is run to setup datadir, databases, tables etc
    //
    
    //
    // database "factory" and its tables are created in setup.prg of they don't exist
    //
    // optional to share data between windows and linux: set samba on
    //
    open database factory 
    local oform = createObject("Form")
    
    // Standalone Apps can optionally require login
    oform.requireslogin = 1
    
    // You can customize the login page using form "parameters"
    oform.parameters = "login.caption=Factory Time Clock;login._background=darkred;login.backgroundimage=img/wallpapers/background.png;login.version=Time Clock Version 1.0;login.copyright=Copyright (c) (2024) LianjaDev. All Rights Reserved Worldwide."
    
    oform.resize(700, 600)
    oform.closable = 1
    oform.caption = "Factory Time clock"
    oform.minwidth = 700
    oform.minheight = 600
    
    // clicking the window "close" button will exit the standalone App
    oform.exitonclose = 1
    
    // move the window to the top of the screen beneath the camera
    oform.move(screenWidth() / 2 - 700 / 2, 20)
    
    oform.addObject("ocont", "container")
    ocont.margin = 10
    ocont.autosize = 1
    ocont.layout = "V"
    ocont.backcolor = "black"
    
    ocont.addObject("obadgenolab", "label")
    obadgenolab.fixedheight = 24
    obadgenolab.autowidth = 1
    obadgenolab.alignment = "center"
    obadgenolab.caption = "Enter Badge Number"
    obadgenolab.backcolor = "darkgray"
    obadgenolab.forecolor = "white"
    obadgenolab.fontbold = 1
    obadgenolab.fontsize = 10
    
    ocont.addspacing(10)
    ocont.addObject("obadgeno", "textbox")
    obadgeno.fixedheight = 24
    obadgeno.autowidth = 1
    obadgeno.inputmask = "@!"
    obadgeno.placeholder = "Enter your badge number, then CLOCK IN or CLOCK OUT"
    
    ocont.addspacing(10)
    ocont.addObject("obadgenolab2", "label")
    obadgenolab2.fixedheight = 24
    obadgenolab2.autowidth = 1
    obadgenolab2.alignment = "center"
    obadgenolab2.caption = "Take a Photo"
    obadgenolab2.backcolor = "darkgray"
    obadgenolab2.forecolor = "white"
    obadgenolab2.fontbold = 1
    obadgenolab2.fontsize = 10
    
    ocont.addspacing(10)
    ocont.addObject("ocamera", "camera")
    ocamera.autowidth = 1
    ocamera.autoheight = 1
    ocamera.backcolor = "black"
    
    ocont.addspacing(10)
    ocont.addObject("obadgenolab3", "label")
    obadgenolab3.fixedheight = 24
    obadgenolab3.autowidth = 1
    obadgenolab3.alignment = "center"
    obadgenolab3.caption = "Clock in / Clock out"
    obadgenolab3.backcolor = "darkgray"
    obadgenolab3.forecolor = "white"
    obadgenolab3.fontbold = 1
    obadgenolab3.fontsize = 10
    
    ocont.addObject("ocont2", "container")
    ocont2.layout = "H"
    ocont2.fixedheight = 60
    ocont2.backcolor = "black"
    ocont2.spacing = 10
    
    ocont2.addObject("obtn1", "commandbutton")  
    obtn1.resize(60, 50)
    obtn1.flat = 1
    obtn1.fixedheight = 50
    obtn1.caption = "CLOCK" + chr(10) + "IN"
    obtn1.stylesheet = "btn"
    ocont2.addObject("obtn2", "commandbutton")  
    obtn2.flat = 1
    obtn2.resize(60, 50)
    obtn2.fixedheight = 50
    obtn2.stylesheet = "btn"
    obtn2.caption = "CLOCK" + chr(10) + "OUT" 
    ocont2.addObject("obtn3", "commandbutton")  
    obtn3.flat = 1
    obtn3.resize(60, 50)
    obtn3.fixedheight = 50
    obtn3.stylesheet = "btn"
    obtn3.caption = "MANAGE" + chr(10) + "CLOCK"
    ocont2.addObject("obtn4", "commandbutton")  
    obtn4.flat = 1
    obtn4.resize(60, 50)
    obtn4.fixedheight = 50
    obtn4.stylesheet = "btn"
    obtn4.caption = "MANAGE" + chr(10) + "EMPLOYEES"
    ocont2.addObject("ocntin", "label")  
    ocntin.resize(60, 50)
    ocntin.fixedheight = 50
    ocntin.alignment = "center"
    ocntin.fontsize = 16
    ocntin.backcolor = "black"
    ocntin.forecolor = "white"
    ocntin.caption = "Clocked In<br>0" 
    ocont2.addObject("ocntout", "label")  
    ocntout.resize(60, 50)
    ocntout.fixedheight = 50
    ocntout.alignment = "center"
    ocntout.fontsize = 16
    ocntout.backcolor = "black"
    ocntout.forecolor = "white"
    ocntout.caption = "Clocked Out<br>0" 
    
    proc updateCounts()
        m_cnt = sqlEval("select cnt(*) from timeclock where empty(clockout)")
        ocntin.caption = "Clocked In<br>" + etos(m_cnt)
        m_cnt = sqlEval("select cnt(*) from timeclock where not empty(clockout)")
        ocntout.caption = "Clocked Out<br>" + etos(m_cnt)
    endproc
    
    // event handlers
    proc clockin()
        local cBadgeno = alltrim(obadgeno.text)
        if len(alltrim(cBadgeno)) = 0
            thisform.showWarningMessage("Please must specify your badge number")
            return
        endif
        local m_cnt = sqlEval("select cnt(*) from employees where badgeno='&cBadgeno'")
        if etos(m_cnt) = "0"
            thisform.showWarningMessage("Unrecognized badge number!")
            return
        endif
        local m_clockout = sqlEval("select clockout from timeclock where badgeno='&cBadgeno' and empty(clockout)")
        if len(alltrim(m_clockout)) > 0
            thisform.showWarningMessage("You must clock out before you can clock in again!")
            return
        endif
        obadgeno.text = ""
        local cPhoto = ocamera.takePhoto()
        insert into timeclock (badgeno, clockin, clockinphoto) values (cBadgeno, datetime(), cPhoto)
        if _tally = 1
            thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())
        else
            thisform.showErrorMessage("Failed to clock in")
        endif
        updateCounts()
    endproc
    
    proc clockout()
        local cBadgeno = alltrim(obadgeno.text)
        if len(alltrim(cBadgeno)) = 0
            thisform.showWarningMessage("Please must specify your badge number")
            return
        endif
        local m_cnt = sqlEval("select cnt(*) from employees where badgeno='&cBadgeno'")
        if etos(m_cnt) = "0"
            thisform.showWarningMessage("Unrecognized badge number!")
            return
        endif
        obadgeno.text = ""
        local m_cnt = sqlEval("select cnt(*) from timeclock where badgeno='&cBadgeno' and empty(clockout)")
        if etos(m_cnt) = "0"
            thisform.showWarningMessage("You must clock in before you can clock out!")
            return
        endif
        local cPhoto = ocamera.takePhoto()
        update timeclock set clockout = datetime(), clockoutphoto = "&cPhoto" where badgeno='&cBadgeno' and empty(clockout)
        if _tally = 1
            thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())
        else
            thisform.showErrorMessage("Failed to clock out")
        endif
        updateCounts()
    endproc
    
    proc admin()
        use timeclock
        browse splitbar ;
            fields badgeno:h="Badge Number", clockin:h="Clock In Time", clockout:h="Clock Out Time" ; 
            properties "splitimagelist=clockinphoto:Clock In Photo,clockoutphoto:Clock Out Photo" ;
            title "Manage Clock"
        use
        updateCounts()
    endproc
    
    proc employees()
        use employees
        browse splitbar ;
            fields badgeno:h="Badge Number", firstname:h="First Name", lastname:h="Last Name" ;
            properties "splitimagelist=photo:Photo" ;
            title "Manage Employees"
        use
        updateCounts()
    endproc
    
    proc afterlogin()
        if username() != "admin"
            obtn3.hide()
            obtn4.hide()
            ocntin.hide()
            ocntout.hide()
        endif
    endproc
    
    // Assign event handlers for the events on UI controls
    oform.afterlogin = afterlogin
    obtn1.click = clockin
    obtn2.click = clockout
    obtn3.click = admin
    obtn4.click = employees
    
    // modal form
    oform.show(1)
    
    // must put read events at the bottom so the window stays open until closed by user
    read events
    See also
    https://www.lianja.com/community/sho...5879#post25879
    Last edited by barrymavin; 2024-03-27 at 05:44.
    Principal developer of Lianja, Recital and other products

    Follow me on:

    Twitter: http://twitter.com/lianjaInc
    Facebook: http://www.facebook.com/LianjaInc
    LinkedIn: http://www.linkedin.com/in/barrymavin

  2. #2
    Member
    Join Date
    Feb 2012
    Location
    São Paulo - Brasil
    Posts
    94
    How I can get frames from camera

  3. #3
    Lianja Development Team barrymavin's Avatar
    Join Date
    Feb 2012
    Location
    UK, USA, Thailand
    Posts
    7,165
    Blog Entries
    22
    Use the getPhoto() method to capture images.

    https://www.lianja.com/doc/index.php/Camera

    What is it you want to achieve?

    Run the example_timeclock App in 9.5.18 as its a fully functional "Factory Time Clock".
    Last edited by barrymavin; 2024-04-10 at 02:32.
    Principal developer of Lianja, Recital and other products

    Follow me on:

    Twitter: http://twitter.com/lianjaInc
    Facebook: http://www.facebook.com/LianjaInc
    LinkedIn: http://www.linkedin.com/in/barrymavin

  4. #4
    Member
    Join Date
    Feb 2012
    Location
    São Paulo - Brasil
    Posts
    94
    I want to make a simple app with face recognition using opencv

  5. #5
    Lianja Development Team barrymavin's Avatar
    Join Date
    Feb 2012
    Location
    UK, USA, Thailand
    Posts
    7,165
    Blog Entries
    22
    Then take a photo using takePhoto() or getPhoto() method and you can use opencast to do the face recognition.
    Principal developer of Lianja, Recital and other products

    Follow me on:

    Twitter: http://twitter.com/lianjaInc
    Facebook: http://www.facebook.com/LianjaInc
    LinkedIn: http://www.linkedin.com/in/barrymavin

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Journey into the Cloud
Join us