Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

How to restrict logging work log for previous month

Sadaf Jabin August 29, 2018

Hi,

Can we restrict the user from logging work for previous month. As per the scenario, I am trying to disable the time spent field in the Log Work Screen, if the Date Started is having a value of previous month. I tried behavior but in vain. Here is my script that I am trying to write using a listener:

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.fields.CustomField;
import com.onresolve.jira.groovy.user.FormField
import com.atlassian.jira.issue.worklog.*
import com.atlassian.jira.issue.MutableIssue

CustomField timespentField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Time Spent")
CustomField startDateField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Date Started")
def today=new Date().format("yyyy-MM-dd")
//def issue = event.issue as Issue
MutableIssue issue = event.issue as MutableIssue
//def startDateVal = issue.getCustomFieldValue(startDateField) as Date
log.error(issue.getCustomFieldValue(startDateField))
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def change = event?.getChangeLog()?.getRelated("ChildChangeItem").find {it.field == "Date Started"}
log.error("change is "+ change)
if(change){
    def startDateVal = issue.getCustomFieldValue(startDateField) as Date
    log.error("start date is "+ startDateVal)
    def month=startDateVal.format("MM")
    def year=startDateVal.format("yyyy")
    Calendar cacheCalendar = Calendar.instance
    cacheCalendar.set(Calendar.MONTH, (Integer.parseInt(month)+1));
    cacheCalendar.set(Calendar.YEAR, Integer.parseInt(year));
    def cutoffDate=cacheCalendar.time.format("yyyy-MM-05")
    def monthStart=startDateVal.format("yyyy-MM-01")
    log.error("Month Start:"+monthStart+"....cutOffDate:"+cutoffDate)
    if(monthStart<=today && today<cutoffDate){
              timespentField.hide();
        issue.timespentField.setVisible(false)
    }
    else {
       getFieldById("log-work-time-logged").setHidden(false)
       timespentField.setRequired(false)
    }
}

Any help will be highly appreciated.

5 answers

1 accepted

0 votes
Answer accepted
Sadaf Jabin August 30, 2018

Hi,

I was able to resolve the problem with script listener.

Logic: Whenever work is logged with a date older than 30 days, we update the worklog date to current date.

Script Listener Events: Issue Worklog Updated, Work Logged on Issue

Script:


import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import java.lang.Object
import com.atlassian.jira.issue.worklog.WorklogImpl2
import java.text.SimpleDateFormat
import com.atlassian.crowd.embedded.api.User
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.worklog.DefaultWorklogManager
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.issue.worklog.Worklog
import com.atlassian.jira.datetime.LocalDate
import com.atlassian.jira.issue.worklog.*

def issue = event.issue as Issue
WorklogManager worklogManager = ComponentAccessor.getWorklogManager()
List worklogs = worklogManager.getByIssue(issue)
def last_worklog=worklogs.last()
def author = last_worklog.getAuthorKey()
def dateformat= new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
def componentManager = ComponentManager.getInstance()
ProjectRoleManager projectRoleManager = ComponentManager.getComponentInstanceOfType(ProjectRoleManager.class) as ProjectRoleManager
def UsersRole = projectRoleManager.getProjectRole("Users")
long timespent = 1
def last_logged=last_worklog.getTimeSpent()
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -30);
Date todate1 = cal.getTime();    
def date_limit = dateformat.format(todate1);
def last_worklog_date=dateformat.format(last_worklog.getStartDate())
log.error(dateformat.parse(last_worklog_date).before(dateformat.parse(date_limit)))
if(last_worklog.getTimeSpent()>1 && dateformat.parse(last_worklog_date).before(dateformat.parse(date_limit))){
String comment=last_logged+'sec logged by '+author+' on date '+last_worklog_date
def worklog = new WorklogImpl2(issue, last_worklog.getId(), author, comment, new Date(), null, null,last_logged, UsersRole)
    worklogManager.update(issue.reporter, worklog, 0L, true)  
}

 

Thanks,

Sadaf Jabin

Prasanth Duggirala
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
May 6, 2019

Hi How can restrict by Future Date to team log the work?

Sadaf Jabin May 7, 2019

HI Prasanth,

Could you please elaborate the problem statement.

Thanks,
Sadaf Jabin

Prasanth Duggirala
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
May 7, 2019

My team members are logging work hours for Future date how can we restrict this.

Sadaf Jabin September 25, 2019

hi Prasanth,

Kindly remove the below line of code from the script:

Calendar cal = Calendar.getInstance();
//cal.add(Calendar.DATE, -30); ---> this makes the limit as 30 days prior to the current date. Commenting it out would make the restriction limit as the current date.
Date todate1 = cal.getTime();  

Like Руслан likes this
Swarna Radha
Contributor
October 20, 2019

Hi @Sadaf Jabin ,

 

I am able to add future dates even I added the script below:

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import java.lang.Object
import com.atlassian.jira.issue.worklog.WorklogImpl2
import java.text.SimpleDateFormat
import com.atlassian.crowd.embedded.api.User
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.worklog.DefaultWorklogManager
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.issue.worklog.Worklog
import com.atlassian.jira.datetime.LocalDate
import com.atlassian.jira.issue.worklog.*
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.user.ApplicationUser

def issueManager = ComponentAccessor.getIssueManager()
def user= ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
MutableIssue issue = event.issue as MutableIssue

WorklogManager worklogManager = ComponentAccessor.getWorklogManager()
List worklogs = worklogManager.getByIssue(issue)
def last_worklog=worklogs.last()
def author = last_worklog.getAuthorKey()
def dateformat= new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
//IssueManager issueManager = ComponentAccessor.getIssueManager();
//def projectRoleManager = ComponentAccessor.getGroupManager()
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
//ProjectRoleManager projectRoleManager = issueManager.getComponentInstanceOfType(ProjectRoleManager.class) as ProjectRoleManager
def UsersRole = projectRoleManager.getProjectRole("Users")
long timespent = 1
def last_logged=last_worklog.getTimeSpent()
Calendar cal = Calendar.getInstance();
//cal.add(Calendar.DATE, -30);
Date todate1 = cal.getTime();
def date_limit = dateformat.format(todate1);
def last_worklog_date=dateformat.format(last_worklog.getStartDate())
log.error(dateformat.parse(last_worklog_date).before(dateformat.parse(date_limit)))
if(last_worklog.getTimeSpent()>1 && dateformat.parse(last_worklog_date).before(dateformat.parse(date_limit))){
String comment=last_logged+'sec logged by '+author+' on date '+last_worklog_date
def worklog = new WorklogImpl2(issue, last_worklog.getId(), author, comment, new Date(), null, null,last_logged, UsersRole)
worklogManager.update(issue.reporter, worklog, 0L, true)
}

 

Thanks,

Swarna

Sadaf Jabin October 21, 2019

@Swarna Radha  Please provide the logs from the listener after entering a future date. Also request you to share the screenshot of the worklog tab for the issue where the efforts are being logged.

Swarna Radha
Contributor
October 21, 2019

Hi @Sadaf Jabin ,

 

Please find attached screenshots of worklog tab and log of listener.

Log Time 2.pngLog time.pngLogs in Listener.png

Sadaf Jabin November 7, 2019

HI @Swarna Radha ,

The code works fine for me. I have added few logs in the code, please update and share the latest log.

def issueManager = ComponentAccessor.getIssueManager()
def user= ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
MutableIssue issue = event.issue as MutableIssue

WorklogManager worklogManager = ComponentAccessor.getWorklogManager()
List worklogs = worklogManager.getByIssue(issue)
def last_worklog=worklogs.last()
def author = last_worklog.getAuthorKey()
def dateformat= new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
//IssueManager issueManager = ComponentAccessor.getIssueManager();
//def projectRoleManager = ComponentAccessor.getGroupManager()
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
//ProjectRoleManager projectRoleManager = issueManager.getComponentInstanceOfType(ProjectRoleManager.class) as ProjectRoleManager
def UsersRole = projectRoleManager.getProjectRole("Users")
long timespent = 1
def last_logged=last_worklog.getTimeSpent()
Calendar cal = Calendar.getInstance();
//cal.add(Calendar.DATE, -30);
Date todate1 = cal.getTime();
def date_limit = dateformat.format(todate1);
def last_worklog_date=dateformat.format(last_worklog.getStartDate())
log.error(dateformat.parse(date_limit).before(dateformat.parse(last_worklog_date)))
log.error(date_limit)
log.error(last_worklog_date)
if(last_worklog.getTimeSpent()>1 && dateformat.parse(date_limit).before(dateformat.parse(last_worklog_date))){
String comment=last_logged+'sec logged by '+author+' on date '+last_worklog_date
log.error(comment)
def worklog = new WorklogImpl2(issue, last_worklog.getId(), author, comment, new Date(), null, null,last_logged, UsersRole)
worklogManager.update(issue.reporter, worklog, 0L, true)
}

Hitesh_Goenka May 27, 2020

@Sadaf Jabin  What is a script listener? Is it an app extension?

Sadaf Jabin May 28, 2020

@Hitesh_GoenkaThis is a script extension we get on installing the scriptrunner plugin.

Bianca Fialho December 14, 2022

Hey guys! I'm needing something similar to this, but I'm not very good at scriptrunner..

I'd need a script that, when a user tries to log work on the previous month, the worklog gets deleted and the user receives a warning that he can't log work for previous month, or a comment is added to the issue letting him know logging is not possible. 

From what I understand, Sadaf's script automatically updates older logs to current dates.

Could you guys give me any pointers on how to adapt this script to just deleting the worklog and warning the user?

Thank you so much!

Sadaf Jabin December 14, 2022

@Bianca FialhoPlease update the logged time to 0.1 minute where worklog is getting updated in the script.

Denise Mendes December 16, 2022

Hi Sadaf, would this change be here on this line?

Captura de tela 2022-12-16 142857.jpg

0 votes
vangapalli jangaiah
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
December 30, 2021

Hi 

 

Any one help me to disable to edit work log entry 

0 votes
mvinod June 5, 2020

Thanks for the update Sadaf.

I tried the same and it is allowing me to log hours for the April Month, at the same time the code also got executed successfully. PFA screen shot for reference. 

Could you please let me know, where do we can see the logs now, Since the code was executed successfully right.

Future_Date_LogWork_2.jpg

Sadaf Jabin June 5, 2020

@mvinod Can you please share the screenshot of the worklog tab of the issue where you logged the effort.  Th work will be logged successfully but the worklog date will appear as the current date.

mvinod June 5, 2020

@Sadaf Jabin  It seems like the date was get updated in the work log tab with the user selected date.

PFB screen shots

WorkLog_1.jpg

 

Listener Log Screen

 

Listener_Log.jpg

mvinod June 5, 2020

@Sadaf Jabin  Could you please let us know , how to debug this code or where to see the logger value which was get executed by this Custom Listener

Sadaf Jabin June 5, 2020

@mvinodyou can click on the green check mark. It will bring up the logs. Please add the logs around the fields you are using in the conditions.

mvinod June 5, 2020

Thank you , Sadaf.

Now, I able to view the log details and listed below the screen shots for reference. Let me start to debug the code to make it work as expected and will let you know, if i need any other inputs.

 

Log_Screen_1.jpg

mvinod June 5, 2020

@Sadaf Jabin 

is it possible to throw error message in the UI Log Work screen itself based on the user selected date validation and i have listed below the screen shot for the same.

 

WorkLog_2.jpg

mvinod June 8, 2020

@Sadaf Jabin 

I referred few blogs and came to know that it is not possible to display error message in UI through Listener.

I re-used your code and am not sure about the logic where you have implemented the future date validation. Since it is always falls into the else block and I have a query here, Instead of updating the future date hours into the current date. Is it possible to disabling the process of updating the hours into the current date. In that case we can restrict the user to log the hours for the future date 

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.component.pico.ComponentManager;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import java.lang.Object
import com.atlassian.jira.issue.worklog.WorklogImpl2
import java.text.SimpleDateFormat
import com.atlassian.crowd.embedded.api.User
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.worklog.DefaultWorklogManager
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.issue.worklog.Worklog
import com.atlassian.jira.datetime.LocalDate
import com.atlassian.jira.issue.worklog.*

def issueManager = ComponentAccessor.getIssueManager()
def user= ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
log.error("user -> " + user);
MutableIssue issue = event.issue as MutableIssue

WorklogManager worklogManager = ComponentAccessor.getWorklogManager()
List worklogs = worklogManager.getByIssue(issue)
def last_worklog=worklogs.last()
//log.error("last_worklog -> " + last_worklog);
def author = last_worklog.getAuthorKey()
log.error("author -> " + author);
def dateformat= new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
//IssueManager issueManager = ComponentAccessor.getIssueManager();
//def projectRoleManager = ComponentAccessor.getGroupManager()
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
//ProjectRoleManager projectRoleManager = issueManager.getComponentInstanceOfType(ProjectRoleManager.class) as ProjectRoleManager
def UsersRole = projectRoleManager.getProjectRole("Users")
log.error("UsersRole -> " + UsersRole);
long timespent = 1
def last_logged=last_worklog.getTimeSpent()
log.error("last_logged -> " + last_logged);
Calendar cal = Calendar.getInstance();
//cal.add(Calendar.DATE, -30);
Date todate1 = cal.getTime();
log.error("todate1 -> " + todate1);
def date_limit = dateformat.format(todate1);
log.error("date_limit -> "+date_limit)
def last_worklog_date=dateformat.format(last_worklog.getStartDate())
log.error("last_worklog_date -> "+last_worklog_date)

log.error("dateformat.parse(date_limit).before(dateformat.parse(last_worklog_date)) -> " + dateformat.parse(date_limit).before(dateformat.parse(last_worklog_date)))

if(last_worklog.getTimeSpent()>1 && dateformat.parse(date_limit).before(dateformat.parse(last_worklog_date))){
log.error("inside if block");
String comment=last_logged+'sec logged by '+author+' on date '+last_worklog_date
log.error("comment -> "+ comment)
log.error("last_worklog.getId() -> "+ last_worklog.getId())
def worklog = new WorklogImpl2(issue, last_worklog.getId(), author, comment, new Date(), null, null,last_logged, UsersRole)
worklogManager.update(issue.reporter, worklog, 0L, true)
} else {
log.error("else block");
}

mvinod June 9, 2020

@Sadaf Jabin 

As per your guidelines and support. I able to restrict the user to log hours for the Future date with the below working code.

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.component.pico.ComponentManager;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import java.lang.Object
import com.atlassian.jira.issue.worklog.WorklogImpl2
import java.text.SimpleDateFormat
import com.atlassian.crowd.embedded.api.User
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.worklog.DefaultWorklogManager
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.issue.worklog.Worklog
import com.atlassian.jira.datetime.LocalDate
import com.atlassian.jira.issue.worklog.*

def issueManager = ComponentAccessor.getIssueManager()
def user= ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
MutableIssue issue = event.issue as MutableIssue
WorklogManager worklogManager = ComponentAccessor.getWorklogManager()
List worklogs = worklogManager.getByIssue(issue)
def last_worklog=worklogs.last()
def author = last_worklog.getAuthorKey()
def dateformat= new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
def UsersRole = projectRoleManager.getProjectRole("Users")
long timespent = 1
def last_logged=last_worklog.getTimeSpent()
log.error("last_logged -> " + last_logged);
Calendar cal = Calendar.getInstance();
//cal.add(Calendar.DATE, -30);
Date todate1 = cal.getTime();
def date_limit = dateformat.format(todate1);
log.error("date_limit -> "+date_limit)
def last_worklog_date=dateformat.format(last_worklog.getStartDate())
log.error("last_worklog_date -> "+last_worklog_date)
log.error(dateformat.parse(date_limit).before(dateformat.parse(last_worklog_date)))

if(last_worklog.getTimeSpent()>1 && dateformat.parse(date_limit).before(dateformat.parse(last_worklog_date))){
String comment=last_logged+'sec logged by '+author+' on date '+last_worklog_date
def worklog = new WorklogImpl2(issue, last_worklog.getId(), author, comment, new Date(), null, null,last_logged, UsersRole)
worklogManager.delete(user, worklog, null, true);
}

 

Now, I would like to avoid making entries in the remaining hours, if user try to enter hrs for the future dates.

Remaining_hrs.jpg

0 votes
mvinod June 4, 2020

Hi Sadaf Jabin,

Did you get any solution from the users or still waiting for the inputs, actually i too want to implement the same and i would like to know how and where we need to implement the logic to validate the work log "Date Started " field in the work log screen 

Sadaf Jabin June 4, 2020

@mvinodPlease refer to the first answer. I was able to acheive the restriction using the shared script.

mvinod June 4, 2020

Thanks for your reply , Sadaf Jabin!

To implement the code , i have navigated to the "Create Listeners" screen under Script Runner. (Listeners -> Create -> Create Listeners).

Now, i am not aware where do we need to place the code and how to debug the code to validate the Date Started  value from the Log Work screen.Script_Listneres.JPG

mvinod June 4, 2020

Hi @ Sadaf Jabin /  @Swarna_Radha ,

I have created a new Custom listener and placed the script code which was shared by Sadaf_Jabin  on Nov 07, 2019. 

PFA screen shoots for the reference.

Now, am not hot to cross check whether the script is running or not (or) do we need to do any other option to make it work. Since in the screen shots it says it was not yet executed in the Execution history column. 

Also kindly let me know, where do we need to view the error log details after the execution of the code.

 

Future_Date_LogWork.jpg

Sadaf Jabin June 5, 2020

@mvinodKindly update the project for which you want this feature enabled. As we can see from the screenshot, it is not associated with any project yet.

mvinod June 5, 2020

Hi Sadaf,

I have removed the project name purposely using MS paint but it is mapped to a project. Let's say it is mapped to Project A.

Sadaf Jabin June 5, 2020

@mvinodIn that case try logging work for the month of April. It will auto update the date to todays date

0 votes
MoroSystems Support
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 30, 2018

Hi Sadaf,

did you considered to use some plugin? I think the Tempo Timesheets plugin should be able to disable logging of work for previous month.

Best regards,

Ondřej

Sadaf Jabin August 30, 2018

Hi Ondřej,

Thanks for your response.

I am actually looking for a solution without having to involve additional plugins. It would be great if you could suggest in that line.

Thanks,

Sadaf Jabin

Deleted user October 29, 2020

Tempo doesn't solve this issue

Like BC likes this

Suggest an answer

Log in or Sign up to answer