Issue with Period Type Validation in Program Stage (v2.42.4)

Dear community,

Please correct me if I am wrong, but my understanding is that the Period Type setting in a Program Stage should limit the number of events a user can create within a specific timeframe (e.g., one event per day for the same Event Date).

However, I believe I have found a bug, which is reproducible on PlayDHIS (v2.42.4). Despite the restrictions, the system still allows multiple events on the same day.

Steps to reproduce:

  1. In the Maintenance app, set a Program Stage to Repeatable and select Daily as the Period Type.
  2. Clear the browser cache.
  3. Open the Capture app and select the specific Program.
  4. Attempt to add multiple events with the same Event Date for a single enrollment.

Actual behavior: The user is still able to create and save multiple events within the same day without any validation errors.

Expected behavior: The system should block the creation of more than one event with the same Event Date if the period type is set to Daily.

Thanks for reporting this!

This feature is a little bit in limbo at the moment - it was implemented (although not perfectly) in Tracker Capture and was even considered for removal (Does anyone use period types for a tracker program?)

Therefore, it has not been prioritized to be implemented in Capture yet (Jira) - but that is why CoP posts like these are great to see that there is a need for it in implementation.

Could you explain your usecase for us? That would also be very helpful.

Thanks!
Karoline
DHIS2 Product Manager

Hi @m.siusko

I’ve added a link to this CoP post in the Jira with the feature request that Karoline posted.

If you have a minute, please… adding more info about the use case and how important the feature is would definitely contribute to giving the feature a little push. Additionally, explaining your use case would help the developers consider it before the software development part.

(BTW, I’m not sure how I missed your post, but luckily Karoline got to it. Thanks @Karoline! :smiling_face_with_three_hearts:)

Hi @Gassim
Sorry for the delayed response.
We would like to restrict users from creating more than one event on the same date.

I see! If you have a minute, would you like to test this suggestion: create a program rule that will check for the expression

d2:lastEventDate('PRVariable-any-dataElementInNewestEventInProgram') == V{event_date} || d2:lastEventDate('PRVariable-any-dataElementInNewestEventInProgram') == V{current_date}

Which will check the date of the previous event, if it is the same as the current date (same day) then it should show an error, and if the date of the previous event is the same as the event_date that the event is being entered for (an event happened a week ago and then I decide to go back and create an new event on the same day of that day), it should also show error.

I’m hoping that this will work, if you think it will satisfy your use-case, would you please test it and validate? :folded_hands:

Thank you!

update:

@m.siusko , I see you’ve marked the post as solved? Would you please explain what worked? Thank you!

Hi @Gassim ,

Thank you for your suggested approach with PR workaround. I will try it and give you feedback soon.

Update It worked. But it is triggering globally, among all OUs and TEIs. My goal is to limit one event per day withing 1 TEI

P.S. Probably I marked it as Solved by mistake. I unmarked it yet.

Hi @m.siusko

Thanks for the update and testing..

This is good to know. Could you clarify a bit more? I don’t understand what you mean by “within one tracked entity instance”? What’s unique about that TEIs that is different from the other TEIs that are in the same program?

If you could explain the real world scenario please, it will help a lot. Thanks!

Hi @Gassim,

Here is my real-world scenario:

  1. Social Helpers are DHIS2 users, each responsible for their own assigned list of clients (TEIs).
  2. Each Social Helper visits their clients and registers one event per client per day - for example, a daily check-in or service delivery record.
  3. The goal is to prevent a Social Helper from accidentally creating more than one event for the same client (TEI) on the same day.
    Thank you in advance

Hi @m.siusko

Thanks for explaining the scenario! I hope that this will give the idea Karoline linked above a push!

Sorry, I didn’t imagine d2:lastEventDate will apply globally!! :laughing:

I would like to suggest a workaround:

  1. Let’s create a data element “Last Event Date” that will be automatically filled with a program rule. Create a program rule with the action to fill the data element with the event_date each time the event is saved.
  2. We will use the same strategy as above but instead of the d2:lastEventDate, we will use our new data element:
    a. Create a program rule variable lastEntryDateVar for the data element “Last Entry Date” with source type “Data element from previous event”.
    b. Create a program rule with a show error action so that it stops from saving a new event with the condition: d2:hasValue('lastEntryDateVar') && (#{lastEntryDateVar} == V{current_date} || #{lastEntryDateVar} == V{event_date})

Do you think this workaround would work? Please let me know if you get the time to test it.

Thanks!

Hi, @Gassim
Maybe I did not understand your approach clearly.

  1. I created a DE “Last Event Date”.
  2. I created a PR “Assign Event Date”:
    • Condition: true
    • Action: Assign value V{event_date} to field “Last Event Date”.
  3. I created a PRV lastEntryDateVar:
    • Source: Data element from previous event
    • DE: Last Event Date
  4. I created a PR “Only One Visit Per Day”:
    • Condition: d2:hasValue(#{lastEntryDateVar}) && (#{lastEntryDateVar} == V{current_date} || #{lastEntryDateVar} == V{event_date})
    • Action: Show warning “One visit per day!” on “Last Event Date”.
      The value is being assigned to the DE “Last Event Date”, but the show error action is not triggering. Also, it is always assigning the current date…

P.S. The only way I solved this issue was by using two DEs:

  • “Current Event Date”
    • PRV Source: DE in current event
    • DE: “Current Event Date”
    • PR: Auto-assign event date
  • “Previous Event Date”
    • PRV Source: DE from previous event
    • DE: “Current Event Date”
    • PR: Auto-assign event date
      The logic is as follows:
  1. During the first event creation, the DE “Current Event Date” is automatically filled with the event date.
  2. When you try to create another event:
    • The DE “Current Event Date” is automatically filled with the event date.
    • The DE “Previous Event Date” takes the value from the DE “Current Event Date” of the previous event.
  3. Finally, a PR with a condition something like this:
    V{program_stage_id} == 'zGxUC78i0pe' && d2:hasValue(#{Previous_Event_date}) && #{Current_Event_date_B} == #{Previous_Event_date}
    shows an error.