Modify

Opened 9 years ago

Closed 9 years ago

#12201 closed defect (fixed)

it is possible to assign ticket to closed milestone

Reported by: nenad@… Owned by: falkb
Priority: normal Component: SimpleMultiProjectPlugin
Severity: normal Keywords:
Cc: Trac Release: 1.0

Description

With multi-projects enabled, and milestones associated to projects, it is possible to set ticket's milestone to the closed one.

Attachments (0)

Change History (24)

comment:1 Changed 9 years ago by anonymous

Why should we restrict that? Have you experienced a special problem?

comment:2 Changed 9 years ago by nenad@…

Well, with ongoing projects that have plenty of milestones set one week apart, once milestone is marked as "completed" it is pointless to allow new tickets to set milestone to any of closed/completed milestones - the list of milestones that appears contains all of them, completed ones are not even marked in any way.

If I'm not mistaken, default Trac beahviour is to present only active milestones in drop-down list.

comment:3 in reply to:  2 ; Changed 9 years ago by Ryan J Ollos

Replying to nenad@…:

If I'm not mistaken, default Trac beahviour is to present only active milestones in drop-down list.

That's correct. However, users with TICKET_ADMIN will see all the milestones grouped by status: Closed, Open (by due date), Open (no due date).

comment:4 in reply to:  3 Changed 9 years ago by nenad@…

Replying to rjollos:

Replying to nenad@…:

If I'm not mistaken, default Trac beahviour is to present only active milestones in drop-down list.

That's correct. However, users with TICKET_ADMIN will see all the milestones grouped by status: Closed, Open (by due date), Open (no due date).

With "SimpleMultiProjectPlugin" plugin activated and with newly created user that does not have "TICKET_ADMIN" permission assigned, but has access to the project itself (definied within Admin / Manage Projects / Project / Restricted To Users), it is still possible to set ticket milestone to the completed one.

User has been granted these permissions:

User  Action               
---------------------------
test  EMAIL_VIEW           
test  FILE_VIEW            
test  LOG_VIEW             
test  MILESTONE_VIEW       
test  PROJECT_SETTINGS_VIEW
test  REPORT_SQL_VIEW      
test  REPORT_VIEW          
test  ROADMAP_VIEW         
test  SEARCH_VIEW          
test  TAGS_MODIFY          
test  TAGS_VIEW            
test  TICKETLOG_VIEW       
test  TICKET_ADD_HOURS     
test  TICKET_APPEND        
test  TICKET_CHGPROP       
test  TICKET_CREATE        
test  TICKET_EDIT_CC       
test  TICKET_EDIT_COMMENT  
test  TICKET_MODIFY        
test  TICKET_VIEW          
test  TICKET_VIEW_HOURS    
test  TIMELINE_VIEW        
test  WIKI_CREATE          
test  WIKI_MODIFY          
test  WIKI_VIEW            
test  WORK_LOG
test  XML_RPC

comment:5 Changed 9 years ago by igor.paunov@…

I have very intensive development and many short milestones (up to two or tree weeks). For one year we have many milestones and is become annoying to pick correct one when creating a ticket.

comment:6 Changed 9 years ago by falkb

Is it OK for you to hide closed milestones from the new ticket form, only? The same ticket form is used also for ticket changes but in such case I'd keep the possibility to fix a milestone or version to an old (closed) one, for cleaning up things so to speak. What do you think?

Last edited 9 years ago by falkb (previous) (diff)

comment:7 Changed 9 years ago by nenad@…

I think that it would be the best if owner of TICKET_ADMIN permission (or, even better, some other/new permission) would have possibility to change milestone to the closed one, but default (for anyone without that permission) to be not to show closed milestones neither in "create new ticket" nor in "modify existing ticket" cases.

Reasoning for this is:

  • when there is a need to change milestone on a per-ticket basis (no 'batch' changes), appearence of closed milestones will again make it hard to do.
  • generally speaking, I believe that it will be confusing for users that on "create new" there won't be closed milestones shown, where the same user that goes to "modify ticket" can see them.

comment:8 Changed 9 years ago by falkb

Yes, that sounds reasonable. I'm going to fix it as you suggested. Let's see if I can find the time this week.

comment:9 Changed 9 years ago by nenad@…

Great! :) Thank you in advance!

comment:10 Changed 9 years ago by falkb

Could you please review the following patch? Take care on the set condition logic:

  • model.py

     
    731731            def execute_sql_statement(db):
    732732                cursor = db.cursor()
    733733                cursor.execute(query, [new_component, old_component])
     734
     735    def is_milestone_completed(self, milestone_name):
     736        db = self.env.get_db_cnx()
     737        cursor = db.cursor()
     738        query = """SELECT completed FROM milestone WHERE name=%s;"""
     739        cursor.execute(query, [milestone_name])
     740        msCompletedDate = cursor.fetchone()
     741        if msCompletedDate and msCompletedDate[0]>0:
     742            return True
     743        return False
  • ticket.py

     
    4242       
    4343    def post_process_request(self, req, template, data, content_type):
    4444        if data and req.path_info.startswith('/ticket'):
     45            is_newticket = False
    4546            ticket = data.get('ticket', None)
    4647            if ticket:
    4748                project_name = self.__SmpModel.get_ticket_project(ticket.id)
    4849                if project_name and project_name[0]:
    4950                    self.__SmpModel.check_project_permission(req, project_name[0])
     51        else:
     52            is_newticket = True
    5053
    5154        if template == 'ticket.html':
    5255            all_components = model.Component.select(self.env)
     
    8083            add_script_data(req, def_version)
    8184            add_script_data(req, project_versions)
    8285           
    83             self._add_milestones_maps(req, data['ticket'])
     86            self._add_milestones_maps(req, data['ticket'], is_newticket)
    8487
    8588        return template, data, content_type
    8689
     
    97100
    98101        return stream
    99102
    100     def _add_milestones_maps(self, req, ticket_data):
     103    def _add_milestones_maps(self, req, ticket_data, is_newticket):
    101104
    102105        milestone = ticket_data.get_value_or_default('milestone')
    103106        project   = ticket_data.get_value_or_default('project')
     
    108111        milestonesForProject = {}
    109112        milestonesForProject[""] = { "Please, select a project!": "" }
    110113
     114        have_ticketadmin = req.perm.has_permission('TICKET_ADMIN')
     115
    111116        for project in sorted(allProjects, key=itemgetter(1)):
    112117            milestones = self.__SmpModel.get_milestones_of_project(project[1])
    113118            milestonesForProject[project[1]] = { "": "" }
    114119            for milestone in sorted(milestones, key=itemgetter(0)):
    115                 milestonesForProject[project[1]][milestone[0]] = milestone[0]
     120                ms = milestone[0]
     121                is_completed   = self.__SmpModel.is_milestone_completed(ms)
     122                hide_milestone = (is_newticket and is_completed) or (not is_newticket and not have_ticketadmin)
     123                if not hide_milestone:
     124                    milestonesForProject[project[1]][ms] = ms
    116125
    117126        smp_milestonesForProject = { 'smp_milestonesForProject' : milestonesForProject }
    118127        smp_initialProjectMilestone = { 'smp_initialProjectMilestone' : initialProjectMilestone }

comment:11 Changed 9 years ago by falkb

Status: newaccepted

comment:12 Changed 9 years ago by nenad@…

It works - TICKET_ADMIN owner can set milestone to closed when modifying existing ticket; new ticket creation offers only open milestones.

comment:13 Changed 9 years ago by falkb

Great! I'm still thinking about the permission, I mean if TICKET_ADMIN is the right one. Stay tuned... Hints very welcome (as always). :-)

comment:14 Changed 9 years ago by nenad@…

Acutally, it may be better to use other permission, as TICKET_ADMIN is already over-used; for example, TICKET_ADMIN is required to make possible to change ticket milestone, and with it you can see all closed ones, too ... In fact, in the first place problem is that TICKET_ADMIN is required for milestone change.

comment:15 Changed 9 years ago by falkb

Actually, it's programmatically quite easy for me to introduce a new plugin permission. See admin.py around line 40:

    def get_permission_actions(self):
        """ Permissions supported by the plugin. """
        return ['PROJECT_ADMIN', 'PROJECT_SETTINGS_VIEW']

One just adds another permission here and it could be used in my patch given in comment:10, though I'm not sure if that's the right way to go.

comment:16 Changed 9 years ago by nenad@…

Yes, I understand you, it would make plugin to behave differently than plain Trac.

comment:17 Changed 9 years ago by falkb

Are you sure you need TICKET_ADMIN for milestone changes since there is T:/TracPermissions#Roadmap with all those MILESTONE_... permissions?

comment:18 Changed 9 years ago by falkb

I also see TICKET_CHGPROP in T:/TracPermissions#TicketSystem which seems to be the smallest one allowing changes to the ticket fields.

comment:19 Changed 9 years ago by falkb

ah forget my comment:17 since we're talking about ticket fields and not managing milestones :)

comment:20 in reply to:  17 Changed 9 years ago by nenad@…

Replying to falkb:

Are you sure you need TICKET_ADMIN for milestone changes since there is T:/TracPermissions#Roadmap with all those MILESTONE_... permissions?

...

I also see TICKET_CHGPROP in ​T:/TracPermissions#TicketSystem which seems to be the smallest one allowing changes to the ticket fields.

Problem is within this patch itself - TICKET_CHGPROP does the job without this patch, with it TICKET_ADMIN is needed. Problem is that with this

hide_milestone = (is_newticket and is_completed) or (not is_newticket and not have_ticketadmin)

we don't take into account case when ticket is not new, milestone is open, and user has TICKET_CHGPROP permission.

comment:21 Changed 9 years ago by falkb

I'm confused and cannot follow you anymore. Can you fix this pseudo code to let it correctly set the variable 'hide_milestone'?

if is_newticket:
    hide_milestone = is_completed
else:
    nenad_case = (not completed and req.perm.has_permission('TICKET_CHGPROP'))
    hide_milestone = not have_ticketadmin or nenad_case

comment:22 Changed 9 years ago by nenad@…

Sorry for the confusion :) I believe code may look like this:

if is_newticket:
    hide_milestone = is_completed
else:
    hide_milestone = not (have_ticketadmin or (not is_completed and req.perm.has_permission('TICKET_CHGPROP')))

comment:23 Changed 9 years ago by falkb

Thanks, now it's clear. :-)

comment:24 Changed 9 years ago by falkb

Resolution: fixed
Status: acceptedclosed

In 14463:

fixes #12201 (thanks to nenad):

  • hide closed milestones from newticket form
  • hide closed milestones from change ticket form under some circumstances (e.g. missing permissions)

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain falkb.
The resolution will be deleted. Next status will be 'reopened'.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.