Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding project on github

  • Loading branch information...
commit e1aa7fcc9f000ae998d538caa7eac9b54d42a501 0 parents
@edmagne edmagne authored
Showing with 876 additions and 0 deletions.
  1. 0  README
  2. +3 −0  README.rdoc
  3. +137 −0 app/controllers/polls_controller.rb
  4. +2 −0  app/helpers/polls_helper.rb
  5. +19 −0 app/models/bet.rb
  6. +3 −0  app/models/eligible_status.rb
  7. +6 −0 app/models/poll_hour.rb
  8. +67 −0 app/views/hooks/.tmp__view_polls_form.rhtml.53897~
  9. +67 −0 app/views/hooks/_view_polls_form.rhtml
  10. +6 −0 app/views/hooks/_view_polls_info.rhtml
  11. +21 −0 app/views/polls/.tmp__config.rhtml.37335~
  12. +36 −0 app/views/polls/.tmp__members.rhtml.45707~
  13. +45 −0 app/views/polls/.tmp_index.rhtml.78401~
  14. +4 −0 app/views/polls/.tmp_index.rhtml.87579~
  15. +18 −0 app/views/polls/_config.rhtml
  16. +36 −0 app/views/polls/_members.rhtml
  17. +4 −0 app/views/polls/index.rhtml
  18. +33 −0 config/locales/en.yml
  19. +33 −0 config/locales/pt-BR.yml
  20. +3 −0  config/routes.rb
  21. +15 −0 db/migrate/001_create_bets.rb
  22. +15 −0 db/migrate/002_create_poll_hours.rb
  23. +9 −0 db/migrate/003_add_bet_hours_to_issues.rb
  24. +11 −0 db/migrate/004_create_eligible_statuses.rb
  25. +28 −0 init.rb
  26. +2 −0  lang/en.yml
  27. +13 −0 lib/issues_polls_hook.rb
  28. +25 −0 lib/issues_polls_issue_patch.rb
  29. +22 −0 lib/issues_polls_project_patch.rb
  30. +60 −0 lib/issues_polls_queries_helper_patch.rb
  31. +32 −0 lib/issues_polls_user_patch.rb
  32. +11 −0 test/fixtures/bets.yml
  33. +7 −0 test/fixtures/eligible_statuses.yml
  34. +11 −0 test/fixtures/poll_hours.yml
  35. +9 −0 test/fixtures/polls.yml
  36. +8 −0 test/functional/polls_controller_test.rb
  37. +5 −0 test/test_helper.rb
  38. +10 −0 test/unit/bet_test.rb
  39. +10 −0 test/unit/eligible_status_test.rb
  40. +10 −0 test/unit/poll_hour_test.rb
  41. +10 −0 test/unit/poll_hours_test.rb
  42. +10 −0 test/unit/poll_test.rb
0  README
No changes.
3  README.rdoc
@@ -0,0 +1,3 @@
+= issue_polls
+
+Description goes here
137 app/controllers/polls_controller.rb
@@ -0,0 +1,137 @@
+class PollsController < ApplicationController
+ unloadable
+
+ before_filter :find_project, :authorize
+ before_filter :get_statuses, :only => [:index, :set_statuses]
+
+ verify :method => [:post], :only => [:set_hours, :set_statuses], :render => { :nothing => true, :status => :method_not_allowed }
+
+ def get_statuses
+ @statuses = IssueStatus.find(:all, :order => 'position')
+ @eligible_statuses = EligibleStatus.find(:all).collect{ |status| status.status_id }
+ end
+
+ def index
+ @users = @project.users.collect {|user| {'login' => user.login, 'fullname' => user.firstname + " " + user.lastname, 'hours' => user.polls_hours_project(@project.id)}}
+ @login = {'order' => 'asc', 'class' => ''}
+ @name = {'order' => 'asc', 'class' => ''}
+ @hours = {'order' => 'asc', 'class' => ''}
+
+ if params[:order_login]
+ if params[:order_login] == "asc"
+ @login = {'order' => 'desc', 'class' => 'sort asc'}
+ @users = @users.sort{|a, b| a['login'] <=> b['login'] }
+ else
+ @login = {'order' => 'asc', 'class' => 'sort desc'}
+ @users = @users.sort{|a, b| b['login'] <=> a['login'] }
+ end
+ elsif params[:order_name]
+ if params[:order_name] == "asc"
+ @name = {'order' => 'desc', 'class' => 'sort asc'}
+ @users = @users.sort{|a, b| a['fullname'] <=> b['fullname'] }
+ else
+ @name = {'order' => 'asc', 'class' => 'sort desc'}
+ @users = @users.sort{|a, b| b['fullname'] <=> a['fullname'] }
+ end
+ elsif params[:order_hours]
+ if params[:order_hours] == "asc"
+ @hours = {'order' => 'desc', 'class' => 'sort asc'}
+ @users = @users.sort{|a, b| a['hours'] <=> b['hours'] }
+ else
+ @hours = {'order' => 'asc', 'class' => 'sort desc'}
+ @users = @users.sort{|a, b| b['hours'] <=> a['hours'] }
+ end
+ else
+ @login = {'order' => 'desc', 'class' => 'sort asc'}
+ @users = @users.sort{|a, b| a['login'] <=> b['login'] }
+ end
+ end
+
+ def set_statuses
+ EligibleStatus.delete_all
+ if params[:statuses]
+ EligibleStatus.create(params[:statuses].collect{|status| {:status_id => status}})
+ end
+ flash[:notice] = t(:configuration_successful)
+ redirect_to :action => 'index', :tab => 'config'
+ end
+
+ def set_hours
+ hours = params[:hours]
+ if /^\d+$/.match(hours)
+ @project.users.each do |user|
+ current_poll_hours = user.poll_hours.find(:first, :conditions => ["project_id = ?", @project.id])
+ if current_poll_hours
+ current_poll_hours.update_attribute(:hours, params[:hours])
+ else
+ user.poll_hours << @project.poll_hours.new(:hours => hours)
+ end
+ end
+ flash[:notice] = t(:assignment_successful)
+ else
+ flash[:error] = l(:invalid_hours)
+ end
+ redirect_to :action => 'index', :tab => 'config'
+ end
+
+ def bet
+ @issue = Issue.find(:first, :conditions => ["id = ? AND project_id = ?", params[:issue_id], @project.id])
+ user = User.current
+ render :update do |page|
+ if @issue and user.can_bet?(@issue.project_id) and @issue.can_receive_bet?
+ @bet = Bet.find(:first, :conditions => ["user_id=? AND issue_id=?", user.id, @issue.id])
+ @new_bet = Bet.new(params[:bet])
+ if @bet
+ @bet.hours += @new_bet.hours
+ else
+ @bet = @new_bet
+ @bet.issue_id = @issue.id
+ @bet.user_id = user.id
+ end
+
+ if @bet.save
+ poll_hour = user.poll_hours.find(:first, :conditions => ["project_id = ?", @issue.project_id])
+ poll_hour.hours -= @new_bet.hours
+ poll_hour.save
+ @issue.bet_hours ||= 0
+ @issue.bet_hours += @new_bet.hours
+ @issue.save
+ page.alert(t(:bet_successful_created))
+ end
+ end
+ page.replace_html :issues_polls_area, :partial => 'hooks/view_polls_form'
+ end
+ end
+
+ def cancel_bet
+ @issue = Issue.find(:first, :conditions => ["id = ? AND project_id = ?", params[:issue_id], @project.id])
+ user = User.current
+
+ render :update do |page|
+ if @issue and user.can_bet?(@issue.project_id) and @issue.can_receive_bet?
+ bet = Bet.find(:first, :conditions => ["user_id=? AND issue_id=?", user.id, @issue.id])
+
+ if bet
+ poll_hour = user.poll_hours.find(:first, :conditions => ["project_id = ?", @issue.project_id])
+ poll_hour.hours += bet.hours
+ poll_hour.save
+ @issue.bet_hours ||= 0
+ @issue.bet_hours -= bet.hours
+ @issue.save
+ bet.destroy
+ page.alert(t(:bet_successful_canceled))
+ end
+ end
+ page.replace_html :issues_polls_area, :partial => 'hooks/view_polls_form'
+ end
+ end
+
+ private
+
+ def find_project
+ @project = Project.find(params[:project_id])
+ rescue ActiveRecord::RecordNotFound
+ render_404
+ end
+
+end
2  app/helpers/polls_helper.rb
@@ -0,0 +1,2 @@
+module PollsHelper
+end
19 app/models/bet.rb
@@ -0,0 +1,19 @@
+class Bet < ActiveRecord::Base
+ unloadable
+ belongs_to :issue
+ belongs_to :user
+
+ validates_presence_of :hours, :user_id, :issue_id
+
+ def validate
+ if self.user and self.issue and self.hours
+ poll_hours = self.user.polls_hours_project(self.issue.project_id)
+ if poll_hours.nil? or (poll_hours and poll_hours < self.hours)
+ self.erros.add_to_base(:error_not_enough_hours)
+ end
+ end
+ end
+
+ private
+
+end
3  app/models/eligible_status.rb
@@ -0,0 +1,3 @@
+class EligibleStatus < ActiveRecord::Base
+ unloadable
+end
6 app/models/poll_hour.rb
@@ -0,0 +1,6 @@
+class PollHour < ActiveRecord::Base
+ unloadable
+ belongs_to :user
+ belongs_to :project
+
+end
67 app/views/hooks/.tmp__view_polls_form.rhtml.53897~
@@ -0,0 +1,67 @@
+<div class="contextual">
+<% if User.current.can_bet?(@issue.project_id) and @issue.can_receive_bet? %>
+ <%= toggle_link l(:link_bet), 'issues-polls-form' %> |
+<% end %>
+ <%= toggle_link l(:link_see_members), 'poll-members' %>
+</div>
+
+<table class="attributes" style="width:60%">
+ <tbody>
+ <tr>
+ <th>
+ <%= t(:label_task_hours_bet) %>:
+ </th>
+ <td>
+ <%= @issue.bet_hours %>
+ </td>
+ <th>
+ <%= t(:label_user_hours) %>:
+ </th>
+ <td>
+ <%= User.current.polls_hours_project(@project.id)%>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<% if User.current.can_bet?(@issue.project_id) and @issue.can_receive_bet? %>
+<%= error_messages_for :bet %>
+<% remote_form_for(:bet, @bet,
+:url => {:controller => 'polls', :action => 'bet', :issue_id => @issue.id, :project_id => @issue.project_id},
+:method => :post,
+:complete => "Form.Element.focus('relation_issue_to_id');",
+:html => {:id => 'issues-polls-form', :style => "display: none"}) do |f| %>
+<div class="flash notice" style="display:none"></div>
+<%= error_messages_for 'bet' %>
+<p>
+ <%= l(:label_bet_hours) %>
+ <%= f.select :hours, 1..User.current.polls_hours_project(@project.id), {} %>
+ <%= l(:label_field_hours) %>
+ <%= submit_tag l(:button_bet) %>
+ <%= toggle_link l(:button_cancel), 'issues-polls-form' %>
+</p>
+<% end %>
+<% end %>
+<table class="list" id="poll-members" style="display: none">
+ <tbody>
+ <tr>
+ <th>
+ <%= t(:label_user_name) %>:
+ </th>
+ <th>
+ <%= t(:label_hours_bet) %>:
+ </th>
+ <th></th>
+ </tr>
+ <% @issue.bets.each do |bet| %>
+ <tr>
+ <td><%= bet.user.name %></td>
+ <td><%= bet.hours %></td>
+ <td>
+ <% if bet.user_id == User.current.id and @issue.can_receive_bet? %>
+ <%= link_to_remote t(:link_cancel_bet), :url => {:controller => 'polls', :action => 'cancel_bet', :issue_id => @issue.id, :project_id => @issue.project_id}, :confirm => t(:confirm_cancel_bet)%>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
67 app/views/hooks/_view_polls_form.rhtml
@@ -0,0 +1,67 @@
+<div class="contextual">
+<% if User.current.can_bet?(@issue.project_id) and @issue.can_receive_bet? %>
+ <%= toggle_link l(:link_bet), 'issues-polls-form' %> |
+<% end %>
+ <%= toggle_link l(:link_see_members), 'poll-members' %>
+</div>
+
+<table class="attributes" style="width:60%">
+ <tbody>
+ <tr>
+ <th>
+ <%= t(:label_task_hours_bet) %>:
+ </th>
+ <td>
+ <%= @issue.bet_hours %>
+ </td>
+ <th>
+ <%= t(:label_user_hours) %>:
+ </th>
+ <td>
+ <%= User.current.polls_hours_project(@project.id)%>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<% if User.current.can_bet?(@issue.project_id) and @issue.can_receive_bet? %>
+<%= error_messages_for :bet %>
+<% remote_form_for(:bet, @bet,
+:url => {:controller => 'polls', :action => 'bet', :issue_id => @issue.id, :project_id => @issue.project_id},
+:method => :post,
+:complete => "Form.Element.focus('relation_issue_to_id');",
+:html => {:id => 'issues-polls-form', :style => "display: none"}) do |f| %>
+<div class="flash notice" style="display:none"></div>
+<%= error_messages_for 'bet' %>
+<p>
+ <%= l(:label_bet_hours) %>
+ <%= f.select :hours, 1..User.current.polls_hours_project(@project.id), {} %>
+ <%= l(:label_field_hours) %>
+ <%= submit_tag l(:button_bet) %>
+ <%= toggle_link l(:button_cancel), 'issues-polls-form' %>
+</p>
+<% end %>
+<% end %>
+<table class="list" id="poll-members" style="display: none">
+ <tbody>
+ <tr>
+ <th>
+ <%= t(:label_user_name) %>:
+ </th>
+ <th>
+ <%= t(:label_hours_bet) %>:
+ </th>
+ <th></th>
+ </tr>
+ <% @issue.bets.each do |bet| %>
+ <tr>
+ <td><%= bet.user.name %></td>
+ <td><%= bet.hours %></td>
+ <td>
+ <% if bet.user_id == User.current.id and @issue.can_receive_bet? %>
+ <%= link_to_remote t(:link_cancel_bet), :url => {:controller => 'polls', :action => 'cancel_bet', :issue_id => @issue.id, :project_id => @issue.project_id}, :confirm => t(:confirm_cancel_bet)%>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
6 app/views/hooks/_view_polls_info.rhtml
@@ -0,0 +1,6 @@
+<% if authorize_for('polls', 'bet') %>
+<hr>
+<div id="issues_polls_area">
+ <%= render :partial => 'hooks/view_polls_form'%>
+</div>
+<% end %>
21 app/views/polls/.tmp__config.rhtml.37335~
@@ -0,0 +1,21 @@
+<p>
+ <h3><%= t(:label_config_status) %></h3>
+ <% form_tag :action => :set_statuses do %>
+ <% @statuses.each do |status| %>
+ <%= check_box_tag "statuses[]", status.id, @eligible_statuses.include?(status.id) %><%= status.name %>
+ <% end %>
+ <%= submit_tag t(:button_set) %>
+ <% end %>
+</p>
+
+
+<p>
+ <h3><%= t(:label_config_hours) %></h3>
+ <% form_tag :controller => 'polls', :action => 'set_hours' do %>
+ <label>
+ <%= l(:field_hours) %>
+ </label>
+ <%= text_field_tag :hours %>
+ <%= submit_tag l(:button_assign) %>
+ <% end %>
+</p>
36 app/views/polls/.tmp__members.rhtml.45707~
@@ -0,0 +1,36 @@
+<% if @project.users.empty? %>
+ <p class="nodata">
+ <%= l(:label_no_data) %>
+ </p>
+<% else %>
+ <table class="list">
+ <thead>
+ <tr>
+ <th>
+ <%= l(:label_user_login) %>
+ </th>
+ <th>
+ <%= l(:label_user_fullname) %>
+ </th>
+ <th>
+ <%= l(:label_field_hours) %>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @project.users.each do |user| %>
+ <tr class="<%= cycle 'odd', 'even' %>">
+ <td>
+ <%= user.login %>
+ </td>
+ <td>
+ <%= user.firstname + " " + user.lastname %>
+ </td>
+ <td>
+ <%= user.polls_hours_project(@project.id) %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+ </table>
+<% end %>
45 app/views/polls/.tmp_index.rhtml.78401~
@@ -0,0 +1,45 @@
+<h2><%=l(:issue_polls_settings) %></h2>
+
+<h3><%= l(:label_members) %></h3>
+<% if @project.users.empty? %>
+<p class="nodata">
+ <%= l(:label_no_data) %>
+</p>
+<% else %>
+<% form_tag :controller => 'polls', :action => 'set_hours' do %>
+ <label><%= l(:field_hours) %></label>
+ <%= text_field_tag :hours %>
+ <%= submit_tag l(:button_set)%>
+<% end %>
+
+<table class="list">
+ <thead>
+ <tr>
+ <th>
+ <%= l(:label_user_login) %>
+ </th>
+ <th>
+ <%= l(:label_user_fullname) %>
+ </th>
+ <th>
+ <%= l(:label_user_hours) %>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @project.users.each do |user| %>
+ <tr class="<%= cycle 'odd', 'even' %>">
+ <td>
+ <%= user.login %>
+ </td>
+ <td>
+ <%= user.firstname + " " + user.lastname %>
+ </td>
+ <td>
+ <%= user.polls_hours_project(@project.id) %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
+<% end %>
4 app/views/polls/.tmp_index.rhtml.87579~
@@ -0,0 +1,4 @@
+<h2><%=l(:issue_polls_dashboard) %></h2>
+
+<%= render_tabs [{:name => 'config', :partial => 'config', :label => :label_config},
+ {:name => 'members', :partial => 'members', :label => :label_members}] %>
18 app/views/polls/_config.rhtml
@@ -0,0 +1,18 @@
+<p>
+ <h3><%= t(:label_config_status) %></h3>
+ <% form_tag :action => :set_statuses do %>
+ <% @statuses.each do |status| %>
+ <p><%= check_box_tag "statuses[]", status.id, @eligible_statuses.include?(status.id), :id => "status#{status.id}" %><label for="status<%= status.id%>"><%= status.name %></label></p>
+ <% end %>
+ <%= submit_tag t(:button_set) %>
+ <% end %>
+</p>
+
+
+<p>
+ <h3><%= t(:label_config_hours) %></h3>
+ <% form_tag :controller => 'polls', :action => 'set_hours' do %>
+ <p><label><%= l(:field_hours) %></label> <%= text_field_tag :hours %></p>
+ <%= submit_tag l(:button_assign) %>
+ <% end %>
+</p>
36 app/views/polls/_members.rhtml
@@ -0,0 +1,36 @@
+<% if @users.empty? %>
+ <p class="nodata">
+ <%= l(:label_no_data) %>
+ </p>
+<% else %>
+ <table class="list">
+ <thead>
+ <tr>
+ <th>
+ <%= link_to l(:label_user_login), {:action => 'index', :order_login => @login['order'], :tab => "members"}, :class => @login['class'] %>
+ </th>
+ <th>
+ <%= link_to l(:label_user_fullname), {:action => 'index', :order_name => @name['order'], :tab => "members"}, :class => @name['class'] %>
+ </th>
+ <th>
+ <%= link_to l(:label_field_hours), {:action => 'index', :order_hours => @hours['order'], :tab => "members"}, :class => @hours['class'] %>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @users.each do |user| %>
+ <tr class="<%= cycle 'odd', 'even' %>">
+ <td>
+ <%= user['login'] %>
+ </td>
+ <td>
+ <%= user['fullname'] %>
+ </td>
+ <td>
+ <%= user['hours'] %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+ </table>
+<% end %>
4 app/views/polls/index.rhtml
@@ -0,0 +1,4 @@
+<h2><%=l(:issue_polls_dashboard) %></h2>
+
+<%= render_tabs [{:name => 'config', :partial => 'config', :label => :label_config},
+ {:name => 'members', :partial => 'members', :label => :label_members}] %>
33 config/locales/en.yml
@@ -0,0 +1,33 @@
+# English strings go here for Rails i18n
+en:
+ issue_polls_caption: "Issue Polls"
+ issue_polls_dashboard: "Issue Polls - dashboard"
+ label_user_login: "Login"
+ label_user_fullname: "Full Name"
+ label_user_hours: "Available Hours"
+ label_members: "Members"
+ label_field_hours: "Polls Hours"
+ label_bet_hours: "bet"
+ label_config: "Settings"
+ label_hours_bet: "Hours bet"
+ label_task_hours_bet: "Task hours bet"
+ label_user_name: "Name"
+ label_config_status: "Task's status eligible"
+ label_config_hours: "Hours assignment for members"
+ bet_successful_created: "Bet successful done"
+ bet_successful_canceled: "Bet successful canceled"
+ configuration_successful: "Configuration successful updated"
+ assignment_successful: "Assignment successful done"
+ field_bet_hours: "Bet hours"
+ button_assign: "Assign"
+ button_set: "Set"
+ button_bet: "Bet"
+ button_cancel: "Cancel"
+ invalid_hours: "Hours must be a integer"
+ link_bet: "Bet"
+ link_cancel_bet: "Cancel bet"
+ link_see_members: "See members"
+ confirm_cancel_bet: "Are you want to cancel bet?"
+ error_not_enough_hours: "You do not have enough hours to this bet"
+ permission_polls_config: "Configuration"
+ permission_bet: "Bet"
33 config/locales/pt-BR.yml
@@ -0,0 +1,33 @@
+# English strings go here for Rails i18n
+pt-BR:
+ issue_polls_caption: "Eleição de tarefas"
+ issue_polls_dashboard: "Eleição de tarefas - painel de controle"
+ label_user_login: "Login"
+ label_user_fullname: "Nome"
+ label_user_hours: "Suas horas disponíveis"
+ label_members: "Membros"
+ label_field_hours: "Horas"
+ label_bet_hours: "apostar"
+ label_config: "Configurações"
+ label_hours_bet: "Horas apostadas"
+ label_task_hours_bet: "Total de horas apostadas na tarefa"
+ label_user_name: "Nome"
+ label_config_status: "Status de tarefas elegíveis"
+ label_config_hours: "Atribuição de horas para membros"
+ bet_successful_created: "Aposta efetuada com sucesso"
+ bet_successful_canceled: "Aposta cancelada com sucesso"
+ configuration_successful: "Configuração alterada com sucesso"
+ assignment_successful: "Atribuição efetuada com sucesso"
+ field_bet_hours: "Horas apostadas"
+ button_assign: "Atribuir"
+ button_set: "Configurar"
+ button_bet: "Apostar"
+ button_cancel: "cancelar"
+ invalid_hours: "Horas deve ser inteiro"
+ link_bet: "Apostar"
+ link_cancel_bet: "Cancelar aposta"
+ link_see_members: "Ver apostadores"
+ confirm_cancel_bet: "Deseja cancelar a aposta?"
+ error_not_enough_hours: "Você não tem horas suficientes para essa aposta"
+ permission_polls_config: "Configurar"
+ permission_bet: "Apostar"
3  config/routes.rb
@@ -0,0 +1,3 @@
+ActionController::Routing::Routes.draw do |map|
+ map.connect 'projects/:project_id/polls/:action', :controller => 'polls'
+end
15 db/migrate/001_create_bets.rb
@@ -0,0 +1,15 @@
+class CreateBets < ActiveRecord::Migration
+ def self.up
+ create_table :bets do |t|
+ t.column :hours, :integer
+ t.column :user_id, :integer
+ t.column :issue_id, :integer
+
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :bets
+ end
+end
15 db/migrate/002_create_poll_hours.rb
@@ -0,0 +1,15 @@
+class CreatePollHours < ActiveRecord::Migration
+ def self.up
+ create_table :poll_hours do |t|
+ t.column :hours, :integer
+ t.column :project_id, :integer
+ t.column :user_id, :integer
+
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :poll_hours
+ end
+end
9 db/migrate/003_add_bet_hours_to_issues.rb
@@ -0,0 +1,9 @@
+class AddBetHoursToIssues < ActiveRecord::Migration
+ def self.up
+ add_column :issues, :bet_hours, :integer, :default => 0
+ end
+
+ def self.down
+ remove_column :issues, :bet_hours
+ end
+end
11 db/migrate/004_create_eligible_statuses.rb
@@ -0,0 +1,11 @@
+class CreateEligibleStatuses < ActiveRecord::Migration
+ def self.up
+ create_table :eligible_statuses do |t|
+ t.column :status_id, :integer
+ end
+ end
+
+ def self.down
+ drop_table :eligible_statuses
+ end
+end
28 init.rb
@@ -0,0 +1,28 @@
+require 'redmine'
+require 'dispatcher'
+
+Dispatcher.to_prepare do
+ require_dependency 'issues_polls_issue_patch'
+ require_dependency 'issues_polls_queries_helper_patch'
+ require_dependency 'issues_polls_user_patch'
+ require_dependency 'issues_polls_project_patch'
+ require_dependency 'issues_polls_hook'
+end
+
+Redmine::Plugin.register :redmine_issues_polls do
+ name 'Redmine Issues Polls plugin'
+ author 'Dextra Sistemas'
+ description 'This is a plugin for Redmine...................'
+ version '0.0.1'
+ url 'http://example.com/path/to/plugin......................'
+ author_url 'http://www.dextra.com.br'
+
+ project_module :issues_polls do
+ permission :permission_polls_config, :polls => [:index, :set_hours, :set_statuses]
+ permission :permission_bet, :polls => [:bet, :cancel_bet]
+ end
+
+ menu :project_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => :issue_polls_caption, :after => :activity, :param => :project_id
+end
+
+
2  lang/en.yml
@@ -0,0 +1,2 @@
+# English strings go here
+my_label: "My label"
13 lib/issues_polls_hook.rb
@@ -0,0 +1,13 @@
+# Provides a link to the issue age graph on the issue index page
+
+module IssuesPolls
+ class Hooks < Redmine::Hook::ViewListener
+ def view_issues_show_details_bottom(context={ })
+ context[:controller].send(:render_to_string, {
+ :partial => 'hooks/view_polls_info',
+ :locals => context
+ })
+ end
+
+ end
+end
25 lib/issues_polls_issue_patch.rb
@@ -0,0 +1,25 @@
+require_dependency 'issue'
+
+module IssuesPollsIssuePatch
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+
+ base.class_eval do
+ has_many :bets
+ end
+
+ end
+
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ def can_receive_bet?
+ EligibleStatus.find(:all).collect{|status| status.status_id}.include?(self.status_id)
+ end
+ end
+
+end
+
+Issue.send(:include, IssuesPollsIssuePatch) unless Issue.included_modules.include? IssuesPollsIssuePatch
22 lib/issues_polls_project_patch.rb
@@ -0,0 +1,22 @@
+require_dependency 'project'
+
+module IssuesPollsProjectPatch
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+
+ base.class_eval do
+ has_many :poll_hours
+ end
+
+ end
+
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ end
+
+end
+
+Project.send(:include, IssuesPollsProjectPatch) unless Project.included_modules.include? IssuesPollsProjectPatch
60 lib/issues_polls_queries_helper_patch.rb
@@ -0,0 +1,60 @@
+require_dependency 'queries_helper'
+
+module IssuesPollsQueriesHelperPatch
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+
+ base.class_eval do
+ alias_method_chain :retrieve_query, :aditional_column
+ end
+
+ end
+
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ def retrieve_query_with_aditional_column
+ if !params[:query_id].blank?
+ cond = "project_id IS NULL"
+ cond << " OR project_id = #{@project.id}" if @project
+ @query = Query.find(params[:query_id], :conditions => cond)
+ raise ::Unauthorized unless @query.visible?
+ @query.project = @project
+ session[:query] = {:id => @query.id, :project_id => @query.project_id}
+ sort_clear
+ else
+ if api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
+ # Give it a name, required to be valid
+ @query = Query.new(:name => "_")
+ @query.project = @project
+ if params[:fields] || params[:f]
+ @query.filters = {}
+ @query.add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
+ else
+ @query.available_filters.keys.each do |field|
+ @query.add_short_filter(field, params[field]) if params[field]
+ end
+ end
+ @query.group_by = params[:group_by]
+ @query.column_names = params[:c] || (params[:query] && params[:query][:column_names])
+ session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
+ else
+ @query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
+ @query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
+ @query.project = @project
+ end
+ end
+ #### Only this was added ####
+ if @project.enabled_module_names.include?('issues_polls')
+ Query.available_columns << QueryColumn.new(:bet_hours, :sortable => "#{Issue.table_name}.bet_hours", :default_order => 'desc')
+ Setting.issue_list_default_columns << "bet_hours"
+ end
+ ##############################
+ end
+ end
+
+end
+
+QueriesHelper.send(:include, IssuesPollsQueriesHelperPatch) unless QueriesHelper.included_modules.include? IssuesPollsQueriesHelperPatch
32 lib/issues_polls_user_patch.rb
@@ -0,0 +1,32 @@
+require_dependency 'user'
+
+module IssuesPollsUserPatch
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+
+ base.class_eval do
+ has_many :poll_hours
+ has_many :bets
+ end
+
+ end
+
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ def polls_hours_project(project_id)
+ hours = poll_hours.find(:first, :conditions => ["project_id = ?", project_id])
+ hours ? hours.hours : nil
+ end
+
+ def can_bet?(project_id)
+ available_hours = self.polls_hours_project(project_id)
+ available_hours and available_hours > 0
+ end
+ end
+
+end
+
+User.send(:include, IssuesPollsUserPatch) unless User.included_modules.include? IssuesPollsUserPatch
11 test/fixtures/bets.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+ hours: 1
+ user_id: 1
+ issue_id: 1
+two:
+ id: 2
+ hours: 1
+ user_id: 1
+ issue_id: 1
7 test/fixtures/eligible_statuses.yml
@@ -0,0 +1,7 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+ status_id: 1
+two:
+ id: 2
+ status_id: 1
11 test/fixtures/poll_hours.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+ hours: 1
+ project_id: 1
+ user_id: 1
+two:
+ id: 2
+ hours: 1
+ project_id: 1
+ user_id: 1
9 test/fixtures/polls.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+ most_voted_id: 1
+ finished: false
+two:
+ id: 2
+ most_voted_id: 1
+ finished: false
8 test/functional/polls_controller_test.rb
@@ -0,0 +1,8 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PollsControllerTest < ActionController::TestCase
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
5 test/test_helper.rb
@@ -0,0 +1,5 @@
+# Load the normal Rails helper
+require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
+
+# Ensure that we are using the temporary fixture path
+Engines::Testing.set_fixture_path
10 test/unit/bet_test.rb
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class BetTest < ActiveSupport::TestCase
+ fixtures :bets
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
10 test/unit/eligible_status_test.rb
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class EligibleStatusTest < ActiveSupport::TestCase
+ fixtures :eligible_statuses
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
10 test/unit/poll_hour_test.rb
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PollHourTest < ActiveSupport::TestCase
+ fixtures :poll_hours
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
10 test/unit/poll_hours_test.rb
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PollHoursTest < ActiveSupport::TestCase
+ fixtures :poll_hours
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
10 test/unit/poll_test.rb
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PollTest < ActiveSupport::TestCase
+ fixtures :polls
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.