Attempt to fetch or exercise a contract not visible to the committer

Hi @Muhammad_Moiz,

There are a few different things to keep apart here:

  1. So-called role templates that are setup as part of some user initialization and then provide non-consuming choices for various actions. In your example, that’s SystemUser and AssociateUser. SystemUser only needs one choice to create a new user. AssociateUser provides a choice to punch in. Note that you need one AssociateUser template per associate.
  2. A running attendance, i.e., the state where the user has punched in but not yet punched out. I would generally recommend to represent different states in different templates so here we can create a special RunningAttendance template for this.
  3. The recorded attendance once the user has punched out. For this we create a new choice on RunningAttendance to punch out and create the final Attendance template. Attendance itself does not provide any choices, it just stores the data for a recorded attendance.

To simplify things a bit, I’ve switched to using DAML’s getTime function but you could stick to passing in the time if you want. There is one issue here where a user can punch in again before having punched out. One option for solving that would be to put a contract key on the RunningAttendance template to enforce uniqueness.

module Main where

import DA.Time

template SystemUser
    with
        name : Text
        user : Party
    where
        signatory user
        nonconsuming choice CreateAssociate : ContractId AssociateUser
          with
            userName : Text
            associate : Party
          controller user
            do create AssociateUser with
                 name = userName
                 associate = associate
                 systemUser = user

template AssociateUser
    with
        name : Text
        associate : Party
        systemUser : Party
    where
        signatory  systemUser
        observer associate
        nonconsuming choice PunchIn : ContractId RunningAttendance
          controller associate
          do punchInTime <- getTime
             create RunningAttendance with
               systemUser
               associate
               punchInTime

template RunningAttendance
  with
    systemUser : Party
    associate : Party
    punchInTime : Time
  where
    signatory systemUser, associate
    choice PunchOut : ContractId Attendance
      controller associate
      do punchOutTime <- getTime
         create Attendance with ..

template Attendance
    with
        systemUser : Party
        associate : Party
        punchInTime : Time
        punchOutTime : Time
    where
        signatory systemUser, associate

setup = do
   systemUser <- getParty "Alice"
   associatedummy <- getParty "Dummy"
   associate  <- getParty "Bob"
   associate1  <- getParty "Bob1"
   uid <- submit systemUser do
        create SystemUser
            with
                name = "Alice"
                user = systemUser
   asid <- submit systemUser $ create AssociateUser
    with
       name = "Bob"
       associate
       systemUser
   running <- submit associate $ exercise asid
     PunchIn
   pass (hours 5)
   submit associate $ exercise running PunchOut
   return ()
3 Likes