Merge branch 'master' into iss-1192-test
3
.gitignore
vendored
@@ -30,4 +30,5 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.ruby-gemset
|
.ruby-gemset
|
||||||
|
|
||||||
public/sitemap.xml
|
public/sitemap.xml
|
||||||
|
public/system/
|
||||||
|
|||||||
4
Capfile
@@ -12,6 +12,10 @@ require 'capistrano/delayed_job'
|
|||||||
require 'whenever/capistrano'
|
require 'whenever/capistrano'
|
||||||
require 'rvm1/capistrano3'
|
require 'rvm1/capistrano3'
|
||||||
|
|
||||||
|
#SCM: Git
|
||||||
|
require "capistrano/scm/git"
|
||||||
|
install_plugin Capistrano::SCM::Git
|
||||||
|
|
||||||
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
|
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
|
||||||
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
||||||
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
|
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
|
||||||
|
|||||||
56
Gemfile
@@ -1,20 +1,20 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
||||||
gem 'rails', '4.2.7.1'
|
gem 'rails', '4.2.8'
|
||||||
# Use PostgreSQL
|
# Use PostgreSQL
|
||||||
gem 'pg', '~> 0.19.0'
|
gem 'pg', '~> 0.20.0'
|
||||||
# Use SCSS for stylesheets
|
# Use SCSS for stylesheets
|
||||||
gem 'sass-rails', '~> 5.0', '>= 5.0.4'
|
gem 'sass-rails', '~> 5.0', '>= 5.0.4'
|
||||||
# Use Uglifier as compressor for JavaScript assets
|
# Use Uglifier as compressor for JavaScript assets
|
||||||
gem 'uglifier', '>= 3.0.4'
|
gem 'uglifier', '~> 3.1.9'
|
||||||
# Use CoffeeScript for .coffee assets and views
|
# Use CoffeeScript for .coffee assets and views
|
||||||
gem 'coffee-rails', '~> 4.2.1'
|
gem 'coffee-rails', '~> 4.2.1'
|
||||||
# See https://github.com/rails/execjs#readme for more supported runtimes
|
# See https://github.com/rails/execjs#readme for more supported runtimes
|
||||||
# gem 'therubyracer', platforms: :ruby
|
# gem 'therubyracer', platforms: :ruby
|
||||||
|
|
||||||
# Use jquery as the JavaScript library
|
# Use jquery as the JavaScript library
|
||||||
gem 'jquery-rails', '~> 4.2.2'
|
gem 'jquery-rails', '~> 4.3.1'
|
||||||
gem 'jquery-ui-rails'
|
gem 'jquery-ui-rails'
|
||||||
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
|
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
|
||||||
gem 'turbolinks'
|
gem 'turbolinks'
|
||||||
@@ -28,10 +28,10 @@ gem 'devise_security_extension'
|
|||||||
# gem 'bcrypt', '~> 3.1.7'
|
# gem 'bcrypt', '~> 3.1.7'
|
||||||
gem 'omniauth'
|
gem 'omniauth'
|
||||||
gem 'omniauth-twitter'
|
gem 'omniauth-twitter'
|
||||||
gem 'omniauth-facebook', '~> 3.0.0'
|
gem 'omniauth-facebook', '~> 4.0.0'
|
||||||
gem 'omniauth-google-oauth2', '~> 0.4.0'
|
gem 'omniauth-google-oauth2', '~> 0.4.0'
|
||||||
|
|
||||||
gem 'kaminari'
|
gem 'kaminari', '~> 1.0.1'
|
||||||
gem 'ancestry', '~> 2.2.2'
|
gem 'ancestry', '~> 2.2.2'
|
||||||
gem 'acts-as-taggable-on'
|
gem 'acts-as-taggable-on'
|
||||||
gem 'responders', '~> 2.3.0'
|
gem 'responders', '~> 2.3.0'
|
||||||
@@ -40,30 +40,32 @@ gem 'foundation_rails_helper', '~> 2.0.0'
|
|||||||
gem 'acts_as_votable'
|
gem 'acts_as_votable'
|
||||||
gem 'ckeditor', '~> 4.2.2'
|
gem 'ckeditor', '~> 4.2.2'
|
||||||
gem 'invisible_captcha', '~> 0.9.2'
|
gem 'invisible_captcha', '~> 0.9.2'
|
||||||
gem 'cancancan'
|
gem 'cancancan', '~> 1.16.0'
|
||||||
gem 'social-share-button'
|
gem 'social-share-button', '~> 0.10'
|
||||||
gem 'initialjs-rails', '0.2.0.4'
|
gem 'initialjs-rails', '0.2.0.4'
|
||||||
gem 'unicorn', '~> 5.2.0'
|
gem 'unicorn', '~> 5.2.0'
|
||||||
gem 'paranoia', '~> 2.2.0'
|
gem 'paranoia', '~> 2.2.1'
|
||||||
gem 'rinku', '~> 2.0.2', require: 'rails_rinku'
|
gem 'rinku', '~> 2.0.2', require: 'rails_rinku'
|
||||||
gem 'savon'
|
gem 'savon'
|
||||||
gem 'dalli'
|
gem 'dalli'
|
||||||
gem 'rollbar', '~> 2.14.0'
|
gem 'rollbar', '~> 2.14.1'
|
||||||
gem 'delayed_job_active_record', '~> 4.1.0'
|
gem 'delayed_job_active_record', '~> 4.1.0'
|
||||||
gem 'daemons'
|
gem 'daemons'
|
||||||
gem 'devise-async'
|
gem 'devise-async'
|
||||||
gem 'newrelic_rpm', '~> 3.17.2.327'
|
gem 'newrelic_rpm', '~> 4.0.0.332'
|
||||||
gem 'whenever', require: false
|
gem 'whenever', require: false
|
||||||
gem 'pg_search'
|
gem 'pg_search'
|
||||||
gem 'sitemap_generator'
|
gem 'sitemap_generator', '~> 5.3.1'
|
||||||
|
|
||||||
gem 'ahoy_matey', '~> 1.5.3'
|
gem 'ahoy_matey', '~> 1.5.5'
|
||||||
gem 'groupdate', '~> 3.1.0' # group temporary data
|
gem 'groupdate', '~> 3.2.0' # group temporary data
|
||||||
gem 'tolk', '~> 2.0.0' # Web interface for translations
|
gem 'tolk', '~> 2.0.0' # Web interface for translations
|
||||||
|
|
||||||
gem 'browser'
|
gem 'browser'
|
||||||
gem 'turnout', '~> 2.4.0'
|
gem 'turnout', '~> 2.4.0'
|
||||||
gem 'redcarpet'
|
gem 'redcarpet', '~> 3.4.0'
|
||||||
|
|
||||||
|
gem 'paperclip'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||||
@@ -72,28 +74,28 @@ group :development, :test do
|
|||||||
gem 'spring'
|
gem 'spring'
|
||||||
gem 'spring-commands-rspec'
|
gem 'spring-commands-rspec'
|
||||||
gem 'rspec-rails', '~> 3.5'
|
gem 'rspec-rails', '~> 3.5'
|
||||||
gem 'capybara'
|
gem 'capybara', '~> 2.13.0'
|
||||||
gem 'factory_girl_rails'
|
gem 'factory_girl_rails', '~> 4.8.0'
|
||||||
gem 'fuubar'
|
gem 'fuubar'
|
||||||
gem 'launchy'
|
gem 'launchy'
|
||||||
gem 'quiet_assets'
|
gem 'quiet_assets'
|
||||||
gem 'letter_opener_web', '~> 1.3.0'
|
gem 'letter_opener_web', '~> 1.3.1'
|
||||||
gem 'i18n-tasks'
|
gem 'i18n-tasks', '~> 0.9.12'
|
||||||
gem 'capistrano', '3.5.0', require: false
|
gem 'capistrano', '~> 3.8.0', require: false
|
||||||
gem 'capistrano-bundler', '~> 1.2', require: false
|
gem 'capistrano-bundler', '~> 1.2', require: false
|
||||||
gem "capistrano-rails", '1.1.8', require: false
|
gem "capistrano-rails", '~> 1.2.3', require: false
|
||||||
gem 'rvm1-capistrano3', require: false
|
gem 'rvm1-capistrano3', require: false
|
||||||
gem 'capistrano3-delayed-job', '~> 1.0'
|
gem 'capistrano3-delayed-job', '~> 1.7.3'
|
||||||
gem "bullet"
|
gem "bullet", '~> 5.5.1'
|
||||||
gem "faker"
|
gem "faker", '~> 1.7.3'
|
||||||
gem 'rubocop', '~> 0.45.0', require: false
|
gem 'rubocop', '~> 0.47.1', require: false
|
||||||
gem 'knapsack'
|
gem 'knapsack'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'database_cleaner'
|
gem 'database_cleaner'
|
||||||
gem 'poltergeist'
|
gem 'poltergeist', '~> 1.14.0'
|
||||||
gem 'coveralls', require: false
|
gem 'coveralls', '~> 0.8.19', require: false
|
||||||
gem 'email_spec'
|
gem 'email_spec'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
296
Gemfile.lock
@@ -1,46 +1,46 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (4.2.7.1)
|
actionmailer (4.2.8)
|
||||||
actionpack (= 4.2.7.1)
|
actionpack (= 4.2.8)
|
||||||
actionview (= 4.2.7.1)
|
actionview (= 4.2.8)
|
||||||
activejob (= 4.2.7.1)
|
activejob (= 4.2.8)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
actionpack (4.2.7.1)
|
actionpack (4.2.8)
|
||||||
actionview (= 4.2.7.1)
|
actionview (= 4.2.8)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.8)
|
||||||
rack (~> 1.6)
|
rack (~> 1.6)
|
||||||
rack-test (~> 0.6.2)
|
rack-test (~> 0.6.2)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (4.2.7.1)
|
actionview (4.2.8)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.8)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||||
activejob (4.2.7.1)
|
activejob (4.2.8)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.8)
|
||||||
globalid (>= 0.3.0)
|
globalid (>= 0.3.0)
|
||||||
activemodel (4.2.7.1)
|
activemodel (4.2.8)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.8)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
activerecord (4.2.7.1)
|
activerecord (4.2.8)
|
||||||
activemodel (= 4.2.7.1)
|
activemodel (= 4.2.8)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.8)
|
||||||
arel (~> 6.0)
|
arel (~> 6.0)
|
||||||
activesupport (4.2.7.1)
|
activesupport (4.2.8)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
json (~> 1.7, >= 1.7.7)
|
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
thread_safe (~> 0.3, >= 0.3.4)
|
thread_safe (~> 0.3, >= 0.3.4)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
acts-as-taggable-on (3.5.0)
|
acts-as-taggable-on (4.0.0)
|
||||||
activerecord (>= 3.2, < 5)
|
activerecord (>= 4.0)
|
||||||
acts_as_votable (0.10.0)
|
acts_as_votable (0.10.0)
|
||||||
addressable (2.4.0)
|
addressable (2.5.0)
|
||||||
ahoy_matey (1.5.3)
|
public_suffix (~> 2.0, >= 2.0.2)
|
||||||
|
ahoy_matey (1.5.5)
|
||||||
addressable
|
addressable
|
||||||
browser (~> 2.0)
|
browser (~> 2.0)
|
||||||
geocoder
|
geocoder
|
||||||
@@ -51,14 +51,14 @@ GEM
|
|||||||
safely_block (>= 0.1.1)
|
safely_block (>= 0.1.1)
|
||||||
user_agent_parser
|
user_agent_parser
|
||||||
uuidtools
|
uuidtools
|
||||||
airbrussh (1.1.1)
|
airbrussh (1.1.2)
|
||||||
sshkit (>= 1.6.1, != 1.7.0)
|
sshkit (>= 1.6.1, != 1.7.0)
|
||||||
akami (1.3.1)
|
akami (1.3.1)
|
||||||
gyoku (>= 0.4.0)
|
gyoku (>= 0.4.0)
|
||||||
nokogiri
|
nokogiri
|
||||||
ancestry (2.2.2)
|
ancestry (2.2.2)
|
||||||
activerecord (>= 3.0.0)
|
activerecord (>= 3.0.0)
|
||||||
arel (6.0.3)
|
arel (6.0.4)
|
||||||
ast (2.3.0)
|
ast (2.3.0)
|
||||||
babel-source (5.8.35)
|
babel-source (5.8.35)
|
||||||
babel-transpiler (0.7.0)
|
babel-transpiler (0.7.0)
|
||||||
@@ -66,28 +66,27 @@ GEM
|
|||||||
execjs (~> 2.0)
|
execjs (~> 2.0)
|
||||||
bcrypt (3.1.11)
|
bcrypt (3.1.11)
|
||||||
browser (2.3.0)
|
browser (2.3.0)
|
||||||
builder (3.2.2)
|
builder (3.2.3)
|
||||||
bullet (5.4.2)
|
bullet (5.5.1)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
uniform_notifier (~> 1.10.0)
|
uniform_notifier (~> 1.10.0)
|
||||||
byebug (9.0.6)
|
byebug (9.0.6)
|
||||||
cancancan (1.15.0)
|
cancancan (1.16.0)
|
||||||
capistrano (3.5.0)
|
capistrano (3.8.0)
|
||||||
airbrussh (>= 1.0.0)
|
airbrussh (>= 1.0.0)
|
||||||
capistrano-harrow
|
|
||||||
i18n
|
i18n
|
||||||
rake (>= 10.0.0)
|
rake (>= 10.0.0)
|
||||||
sshkit (>= 1.9.0)
|
sshkit (>= 1.9.0)
|
||||||
capistrano-bundler (1.2.0)
|
capistrano-bundler (1.2.0)
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
sshkit (~> 1.2)
|
sshkit (~> 1.2)
|
||||||
capistrano-harrow (0.5.3)
|
capistrano-rails (1.2.3)
|
||||||
capistrano-rails (1.1.8)
|
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
capistrano-bundler (~> 1.1)
|
capistrano-bundler (~> 1.1)
|
||||||
capistrano3-delayed-job (1.7.2)
|
capistrano3-delayed-job (1.7.3)
|
||||||
capistrano (~> 3.0, >= 3.0.0)
|
capistrano (~> 3.0, >= 3.0.0)
|
||||||
capybara (2.7.1)
|
daemons (~> 1.2.4)
|
||||||
|
capybara (2.13.0)
|
||||||
addressable
|
addressable
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
nokogiri (>= 1.3.3)
|
nokogiri (>= 1.3.3)
|
||||||
@@ -109,9 +108,9 @@ GEM
|
|||||||
coffee-script (2.4.1)
|
coffee-script (2.4.1)
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
execjs
|
execjs
|
||||||
coffee-script-source (1.10.0)
|
coffee-script-source (1.12.2)
|
||||||
concurrent-ruby (1.0.4)
|
concurrent-ruby (1.0.5)
|
||||||
coveralls (0.8.17)
|
coveralls (0.8.19)
|
||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
simplecov (~> 0.12.0)
|
simplecov (~> 0.12.0)
|
||||||
term-ansicolor (~> 1.3)
|
term-ansicolor (~> 1.3)
|
||||||
@@ -151,14 +150,14 @@ GEM
|
|||||||
errbase (0.0.3)
|
errbase (0.0.3)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
execjs (2.7.0)
|
execjs (2.7.0)
|
||||||
factory_girl (4.7.0)
|
factory_girl (4.8.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
factory_girl_rails (4.7.0)
|
factory_girl_rails (4.8.0)
|
||||||
factory_girl (~> 4.7.0)
|
factory_girl (~> 4.8.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
faker (1.6.6)
|
faker (1.7.3)
|
||||||
i18n (~> 0.5)
|
i18n (~> 0.5)
|
||||||
faraday (0.9.2)
|
faraday (0.11.0)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
foundation-rails (6.2.4.0)
|
foundation-rails (6.2.4.0)
|
||||||
railties (>= 3.1.0)
|
railties (>= 3.1.0)
|
||||||
@@ -173,20 +172,20 @@ GEM
|
|||||||
fuubar (2.2.0)
|
fuubar (2.2.0)
|
||||||
rspec-core (~> 3.0)
|
rspec-core (~> 3.0)
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
geocoder (1.4.1)
|
geocoder (1.4.3)
|
||||||
globalid (0.3.7)
|
globalid (0.3.7)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
groupdate (3.1.1)
|
groupdate (3.2.0)
|
||||||
activesupport (>= 3)
|
activesupport (>= 3)
|
||||||
gyoku (1.3.1)
|
gyoku (1.3.1)
|
||||||
builder (>= 2.1.2)
|
builder (>= 2.1.2)
|
||||||
hashie (3.4.6)
|
hashie (3.5.5)
|
||||||
highline (1.7.8)
|
highline (1.7.8)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
httpi (2.4.1)
|
httpi (2.4.1)
|
||||||
rack
|
rack
|
||||||
i18n (0.7.0)
|
i18n (0.8.1)
|
||||||
i18n-tasks (0.9.6)
|
i18n-tasks (0.9.12)
|
||||||
activesupport (>= 4.0.2)
|
activesupport (>= 4.0.2)
|
||||||
ast (>= 2.1.0)
|
ast (>= 2.1.0)
|
||||||
easy_translate (>= 0.5.0)
|
easy_translate (>= 0.5.0)
|
||||||
@@ -200,26 +199,35 @@ GEM
|
|||||||
railties (>= 3.1, < 6.0)
|
railties (>= 3.1, < 6.0)
|
||||||
invisible_captcha (0.9.2)
|
invisible_captcha (0.9.2)
|
||||||
rails (>= 3.2.0)
|
rails (>= 3.2.0)
|
||||||
jquery-rails (4.2.2)
|
jquery-rails (4.3.1)
|
||||||
rails-dom-testing (>= 1, < 3)
|
rails-dom-testing (>= 1, < 3)
|
||||||
railties (>= 4.2.0)
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
jquery-ui-rails (5.0.5)
|
jquery-ui-rails (6.0.1)
|
||||||
railties (>= 3.2.16)
|
railties (>= 3.2.16)
|
||||||
json (1.8.3)
|
json (2.0.3)
|
||||||
jwt (1.5.4)
|
jwt (1.5.6)
|
||||||
kaminari (0.17.0)
|
kaminari (1.0.1)
|
||||||
actionpack (>= 3.0.0)
|
activesupport (>= 4.1.0)
|
||||||
activesupport (>= 3.0.0)
|
kaminari-actionview (= 1.0.1)
|
||||||
|
kaminari-activerecord (= 1.0.1)
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-actionview (1.0.1)
|
||||||
|
actionview
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-activerecord (1.0.1)
|
||||||
|
activerecord
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-core (1.0.1)
|
||||||
kgio (2.11.0)
|
kgio (2.11.0)
|
||||||
knapsack (1.13.1)
|
knapsack (1.13.2)
|
||||||
rake
|
rake
|
||||||
timecop (>= 0.1.0)
|
timecop (>= 0.1.0)
|
||||||
launchy (2.4.3)
|
launchy (2.4.3)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
letter_opener (1.4.1)
|
letter_opener (1.4.1)
|
||||||
launchy (~> 2.2)
|
launchy (~> 2.2)
|
||||||
letter_opener_web (1.3.0)
|
letter_opener_web (1.3.1)
|
||||||
actionmailer (>= 3.2)
|
actionmailer (>= 3.2)
|
||||||
letter_opener (~> 1.0)
|
letter_opener (~> 1.0)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
@@ -230,29 +238,30 @@ GEM
|
|||||||
mime-types (3.1)
|
mime-types (3.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2016.0521)
|
mime-types-data (3.2016.0521)
|
||||||
|
mimemagic (0.3.2)
|
||||||
mini_portile2 (2.1.0)
|
mini_portile2 (2.1.0)
|
||||||
minitest (5.10.1)
|
minitest (5.10.1)
|
||||||
multi_json (1.12.1)
|
multi_json (1.12.1)
|
||||||
multi_xml (0.5.5)
|
multi_xml (0.6.0)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
net-scp (1.2.1)
|
net-scp (1.2.1)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (3.2.0)
|
net-ssh (4.1.0)
|
||||||
newrelic_rpm (3.17.2.327)
|
newrelic_rpm (4.0.0.332)
|
||||||
nokogiri (1.6.8.1)
|
nokogiri (1.7.1)
|
||||||
mini_portile2 (~> 2.1.0)
|
mini_portile2 (~> 2.1.0)
|
||||||
nori (2.6.0)
|
nori (2.6.0)
|
||||||
oauth (0.5.0)
|
oauth (0.5.1)
|
||||||
oauth2 (1.0.0)
|
oauth2 (1.3.1)
|
||||||
faraday (>= 0.8, < 0.10)
|
faraday (>= 0.8, < 0.12)
|
||||||
jwt (~> 1.0)
|
jwt (~> 1.0)
|
||||||
multi_json (~> 1.3)
|
multi_json (~> 1.3)
|
||||||
multi_xml (~> 0.5)
|
multi_xml (~> 0.5)
|
||||||
rack (~> 1.2)
|
rack (>= 1.2, < 3)
|
||||||
omniauth (1.3.1)
|
omniauth (1.6.1)
|
||||||
hashie (>= 1.2, < 4)
|
hashie (>= 3.4.6, < 3.6.0)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.6.2, < 3)
|
||||||
omniauth-facebook (3.0.0)
|
omniauth-facebook (4.0.0)
|
||||||
omniauth-oauth2 (~> 1.2)
|
omniauth-oauth2 (~> 1.2)
|
||||||
omniauth-google-oauth2 (0.4.1)
|
omniauth-google-oauth2 (0.4.1)
|
||||||
jwt (~> 1.5.2)
|
jwt (~> 1.5.2)
|
||||||
@@ -265,24 +274,31 @@ GEM
|
|||||||
omniauth-oauth2 (1.4.0)
|
omniauth-oauth2 (1.4.0)
|
||||||
oauth2 (~> 1.0)
|
oauth2 (~> 1.0)
|
||||||
omniauth (~> 1.2)
|
omniauth (~> 1.2)
|
||||||
omniauth-twitter (1.2.1)
|
omniauth-twitter (1.4.0)
|
||||||
json (~> 1.3)
|
|
||||||
omniauth-oauth (~> 1.1)
|
omniauth-oauth (~> 1.1)
|
||||||
|
rack
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paranoia (2.2.0)
|
paperclip (5.1.0)
|
||||||
|
activemodel (>= 4.2.0)
|
||||||
|
activesupport (>= 4.2.0)
|
||||||
|
cocaine (~> 0.5.5)
|
||||||
|
mime-types
|
||||||
|
mimemagic (~> 0.3.0)
|
||||||
|
paranoia (2.2.1)
|
||||||
activerecord (>= 4.0, < 5.1)
|
activerecord (>= 4.0, < 5.1)
|
||||||
parser (2.3.3.1)
|
parser (2.4.0.0)
|
||||||
ast (~> 2.2)
|
ast (~> 2.2)
|
||||||
pg (0.19.0)
|
pg (0.20.0)
|
||||||
pg_search (1.0.6)
|
pg_search (2.0.1)
|
||||||
activerecord (>= 3.1)
|
activerecord (>= 4.2)
|
||||||
activesupport (>= 3.1)
|
activesupport (>= 4.2)
|
||||||
arel
|
arel (>= 6)
|
||||||
poltergeist (1.10.0)
|
poltergeist (1.14.0)
|
||||||
capybara (~> 2.1)
|
capybara (~> 2.1)
|
||||||
cliver (~> 0.3.1)
|
cliver (~> 0.3.1)
|
||||||
websocket-driver (>= 0.2.0)
|
websocket-driver (>= 0.2.0)
|
||||||
powerpack (0.1.1)
|
powerpack (0.1.1)
|
||||||
|
public_suffix (2.0.5)
|
||||||
quiet_assets (1.1.0)
|
quiet_assets (1.1.0)
|
||||||
railties (>= 3.1, < 5.0)
|
railties (>= 3.1, < 5.0)
|
||||||
rack (1.6.5)
|
rack (1.6.5)
|
||||||
@@ -292,40 +308,40 @@ GEM
|
|||||||
rack
|
rack
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.2.7.1)
|
rails (4.2.8)
|
||||||
actionmailer (= 4.2.7.1)
|
actionmailer (= 4.2.8)
|
||||||
actionpack (= 4.2.7.1)
|
actionpack (= 4.2.8)
|
||||||
actionview (= 4.2.7.1)
|
actionview (= 4.2.8)
|
||||||
activejob (= 4.2.7.1)
|
activejob (= 4.2.8)
|
||||||
activemodel (= 4.2.7.1)
|
activemodel (= 4.2.8)
|
||||||
activerecord (= 4.2.7.1)
|
activerecord (= 4.2.8)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.8)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.2.7.1)
|
railties (= 4.2.8)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
rails-deprecated_sanitizer (1.0.3)
|
rails-deprecated_sanitizer (1.0.3)
|
||||||
activesupport (>= 4.2.0.alpha)
|
activesupport (>= 4.2.0.alpha)
|
||||||
rails-dom-testing (1.0.7)
|
rails-dom-testing (1.0.8)
|
||||||
activesupport (>= 4.2.0.beta, < 5.0)
|
activesupport (>= 4.2.0.beta, < 5.0)
|
||||||
nokogiri (~> 1.6.0)
|
nokogiri (~> 1.6)
|
||||||
rails-deprecated_sanitizer (>= 1.0.1)
|
rails-deprecated_sanitizer (>= 1.0.1)
|
||||||
rails-html-sanitizer (1.0.3)
|
rails-html-sanitizer (1.0.3)
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.0)
|
||||||
railties (4.2.7.1)
|
railties (4.2.8)
|
||||||
actionpack (= 4.2.7.1)
|
actionpack (= 4.2.8)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.8)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (2.1.0)
|
rainbow (2.2.1)
|
||||||
raindrops (0.17.0)
|
raindrops (0.17.0)
|
||||||
rake (12.0.0)
|
rake (12.0.0)
|
||||||
redcarpet (3.3.4)
|
redcarpet (3.4.0)
|
||||||
referer-parser (0.3.0)
|
referer-parser (0.3.0)
|
||||||
request_store (1.3.1)
|
request_store (1.3.2)
|
||||||
responders (2.3.0)
|
responders (2.3.0)
|
||||||
railties (>= 4.2.0, < 5.1)
|
railties (>= 4.2.0, < 5.1)
|
||||||
rinku (2.0.2)
|
rinku (2.0.2)
|
||||||
rollbar (2.14.0)
|
rollbar (2.14.1)
|
||||||
multi_json
|
multi_json
|
||||||
rspec-core (3.5.4)
|
rspec-core (3.5.4)
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.5.0)
|
||||||
@@ -344,8 +360,8 @@ GEM
|
|||||||
rspec-mocks (~> 3.5.0)
|
rspec-mocks (~> 3.5.0)
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-support (3.5.0)
|
rspec-support (3.5.0)
|
||||||
rubocop (0.45.0)
|
rubocop (0.47.1)
|
||||||
parser (>= 2.3.1.1, < 3.0)
|
parser (>= 2.3.3.1, < 3.0)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 1.99.1, < 3.0)
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
@@ -355,9 +371,9 @@ GEM
|
|||||||
capistrano (~> 3.0)
|
capistrano (~> 3.0)
|
||||||
sshkit (>= 1.2)
|
sshkit (>= 1.2)
|
||||||
safe_yaml (1.0.4)
|
safe_yaml (1.0.4)
|
||||||
safely_block (0.1.1)
|
safely_block (0.2.0)
|
||||||
errbase
|
errbase
|
||||||
sass (3.4.22)
|
sass (3.4.23)
|
||||||
sass-rails (5.0.6)
|
sass-rails (5.0.6)
|
||||||
railties (>= 4.0.0, < 6)
|
railties (>= 4.0.0, < 6)
|
||||||
sass (~> 3.1)
|
sass (~> 3.1)
|
||||||
@@ -377,12 +393,12 @@ GEM
|
|||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
simplecov-html (~> 0.10.0)
|
simplecov-html (~> 0.10.0)
|
||||||
simplecov-html (0.10.0)
|
simplecov-html (0.10.0)
|
||||||
sitemap_generator (5.2.0)
|
sitemap_generator (5.3.1)
|
||||||
builder (~> 3.0)
|
builder (~> 3.0)
|
||||||
social-share-button (0.3.1)
|
social-share-button (0.10.0)
|
||||||
coffee-rails
|
coffee-rails
|
||||||
sass-rails
|
spring (2.0.1)
|
||||||
spring (1.7.2)
|
activesupport (>= 4.2)
|
||||||
spring-commands-rspec (1.0.4)
|
spring-commands-rspec (1.0.4)
|
||||||
spring (>= 0.9.1)
|
spring (>= 0.9.1)
|
||||||
sprockets (3.7.1)
|
sprockets (3.7.1)
|
||||||
@@ -396,7 +412,7 @@ GEM
|
|||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
sshkit (1.11.4)
|
sshkit (1.12.0)
|
||||||
net-scp (>= 1.1.2)
|
net-scp (>= 1.1.2)
|
||||||
net-ssh (>= 2.8.0)
|
net-ssh (>= 2.8.0)
|
||||||
term-ansicolor (1.4.0)
|
term-ansicolor (1.4.0)
|
||||||
@@ -405,10 +421,10 @@ GEM
|
|||||||
unicode-display_width (~> 1.1.1)
|
unicode-display_width (~> 1.1.1)
|
||||||
thor (0.19.4)
|
thor (0.19.4)
|
||||||
thread (0.2.2)
|
thread (0.2.2)
|
||||||
thread_safe (0.3.5)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.5)
|
tilt (2.0.7)
|
||||||
timecop (0.8.1)
|
timecop (0.8.1)
|
||||||
tins (1.13.0)
|
tins (1.13.2)
|
||||||
tolk (2.0.0)
|
tolk (2.0.0)
|
||||||
rails (>= 4.0)
|
rails (>= 4.0)
|
||||||
safe_yaml (>= 0.8.6)
|
safe_yaml (>= 0.8.6)
|
||||||
@@ -421,9 +437,9 @@ GEM
|
|||||||
tilt (>= 1.4, < 3)
|
tilt (>= 1.4, < 3)
|
||||||
tzinfo (1.2.2)
|
tzinfo (1.2.2)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (3.0.4)
|
uglifier (3.1.9)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
unicode-display_width (1.1.1)
|
unicode-display_width (1.1.3)
|
||||||
unicorn (5.2.0)
|
unicorn (5.2.0)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
@@ -439,7 +455,7 @@ GEM
|
|||||||
activemodel (>= 4.2)
|
activemodel (>= 4.2)
|
||||||
debug_inspector
|
debug_inspector
|
||||||
railties (>= 4.2)
|
railties (>= 4.2)
|
||||||
websocket-driver (0.6.4)
|
websocket-driver (0.6.5)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.2)
|
websocket-extensions (0.1.2)
|
||||||
whenever (0.9.7)
|
whenever (0.9.7)
|
||||||
@@ -453,20 +469,20 @@ PLATFORMS
|
|||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
acts-as-taggable-on
|
acts-as-taggable-on
|
||||||
acts_as_votable
|
acts_as_votable
|
||||||
ahoy_matey (~> 1.5.3)
|
ahoy_matey (~> 1.5.5)
|
||||||
ancestry (~> 2.2.2)
|
ancestry (~> 2.2.2)
|
||||||
browser
|
browser
|
||||||
bullet
|
bullet (~> 5.5.1)
|
||||||
byebug
|
byebug
|
||||||
cancancan
|
cancancan (~> 1.16.0)
|
||||||
capistrano (= 3.5.0)
|
capistrano (~> 3.8.0)
|
||||||
capistrano-bundler (~> 1.2)
|
capistrano-bundler (~> 1.2)
|
||||||
capistrano-rails (= 1.1.8)
|
capistrano-rails (~> 1.2.3)
|
||||||
capistrano3-delayed-job (~> 1.0)
|
capistrano3-delayed-job (~> 1.7.3)
|
||||||
capybara
|
capybara (~> 2.13.0)
|
||||||
ckeditor (~> 4.2.2)
|
ckeditor (~> 4.2.2)
|
||||||
coffee-rails (~> 4.2.1)
|
coffee-rails (~> 4.2.1)
|
||||||
coveralls
|
coveralls (~> 0.8.19)
|
||||||
daemons
|
daemons
|
||||||
dalli
|
dalli
|
||||||
database_cleaner
|
database_cleaner
|
||||||
@@ -475,50 +491,54 @@ DEPENDENCIES
|
|||||||
devise-async
|
devise-async
|
||||||
devise_security_extension
|
devise_security_extension
|
||||||
email_spec
|
email_spec
|
||||||
factory_girl_rails
|
factory_girl_rails (~> 4.8.0)
|
||||||
faker
|
faker (~> 1.7.3)
|
||||||
foundation-rails (~> 6.2.4.0)
|
foundation-rails (~> 6.2.4.0)
|
||||||
foundation_rails_helper (~> 2.0.0)
|
foundation_rails_helper (~> 2.0.0)
|
||||||
fuubar
|
fuubar
|
||||||
groupdate (~> 3.1.0)
|
groupdate (~> 3.2.0)
|
||||||
i18n-tasks
|
i18n-tasks (~> 0.9.12)
|
||||||
initialjs-rails (= 0.2.0.4)
|
initialjs-rails (= 0.2.0.4)
|
||||||
invisible_captcha (~> 0.9.2)
|
invisible_captcha (~> 0.9.2)
|
||||||
jquery-rails (~> 4.2.2)
|
jquery-rails (~> 4.3.1)
|
||||||
jquery-ui-rails
|
jquery-ui-rails
|
||||||
kaminari
|
kaminari (~> 1.0.1)
|
||||||
knapsack
|
knapsack
|
||||||
launchy
|
launchy
|
||||||
letter_opener_web (~> 1.3.0)
|
letter_opener_web (~> 1.3.1)
|
||||||
newrelic_rpm (~> 3.17.2.327)
|
newrelic_rpm (~> 4.0.0.332)
|
||||||
omniauth
|
omniauth
|
||||||
omniauth-facebook (~> 3.0.0)
|
omniauth-facebook (~> 4.0.0)
|
||||||
omniauth-google-oauth2 (~> 0.4.0)
|
omniauth-google-oauth2 (~> 0.4.0)
|
||||||
omniauth-twitter
|
omniauth-twitter
|
||||||
paranoia (~> 2.2.0)
|
paperclip
|
||||||
pg (~> 0.19.0)
|
paranoia (~> 2.2.1)
|
||||||
|
pg (~> 0.20.0)
|
||||||
pg_search
|
pg_search
|
||||||
poltergeist
|
poltergeist (~> 1.14.0)
|
||||||
quiet_assets
|
quiet_assets
|
||||||
rails (= 4.2.7.1)
|
rails (= 4.2.8)
|
||||||
redcarpet
|
redcarpet (~> 3.4.0)
|
||||||
responders (~> 2.3.0)
|
responders (~> 2.3.0)
|
||||||
rinku (~> 2.0.2)
|
rinku (~> 2.0.2)
|
||||||
rollbar (~> 2.14.0)
|
rollbar (~> 2.14.1)
|
||||||
rspec-rails (~> 3.5)
|
rspec-rails (~> 3.5)
|
||||||
rubocop (~> 0.45.0)
|
rubocop (~> 0.47.1)
|
||||||
rvm1-capistrano3
|
rvm1-capistrano3
|
||||||
sass-rails (~> 5.0, >= 5.0.4)
|
sass-rails (~> 5.0, >= 5.0.4)
|
||||||
savon
|
savon
|
||||||
sitemap_generator
|
sitemap_generator (~> 5.3.1)
|
||||||
social-share-button
|
social-share-button (~> 0.10)
|
||||||
spring
|
spring
|
||||||
spring-commands-rspec
|
spring-commands-rspec
|
||||||
sprockets (~> 3.7.1)
|
sprockets (~> 3.7.1)
|
||||||
tolk (~> 2.0.0)
|
tolk (~> 2.0.0)
|
||||||
turbolinks
|
turbolinks
|
||||||
turnout (~> 2.4.0)
|
turnout (~> 2.4.0)
|
||||||
uglifier (>= 3.0.4)
|
uglifier (~> 3.1.9)
|
||||||
unicorn (~> 5.2.0)
|
unicorn (~> 5.2.0)
|
||||||
web-console (= 3.3.0)
|
web-console (= 3.3.0)
|
||||||
whenever
|
whenever
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.14.6
|
||||||
|
|||||||
10
README.md
@@ -1,15 +1,19 @@
|
|||||||
![Logo of Consul]
|

|
||||||
(https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png)
|
|
||||||
|
|
||||||
# Consul
|
# Consul
|
||||||
|
|
||||||
Citizen Participation and Open Government Application
|
Citizen Participation and Open Government Application
|
||||||
|
|
||||||
[](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
[](https://travis-ci.org/consul/consul)
|
[](https://travis-ci.org/consul/consul)
|
||||||
[](https://codeclimate.com/github/consul/consul)
|
[](https://codeclimate.com/github/consul/consul)
|
||||||
[](https://gemnasium.com/consul/consul)
|
[](https://gemnasium.com/consul/consul)
|
||||||
[](https://coveralls.io/github/consul/consul?branch=master)
|
[](https://coveralls.io/github/consul/consul?branch=master)
|
||||||
|
[](http://www.gnu.org/licenses/agpl-3.0)
|
||||||
|
|
||||||
|
[](https://www.w3.org/WAI/eval/Overview)
|
||||||
|
[](https://rocketvalidator.com/opensource)
|
||||||
|
|
||||||
|
[](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website
|
This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website
|
||||||
|
|
||||||
|
|||||||
11
README_ES.md
@@ -1,15 +1,20 @@
|
|||||||
![Logotipo de Consul]
|

|
||||||
(https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png)
|
|
||||||
|
|
||||||
# Consul
|
# Consul
|
||||||
|
|
||||||
Aplicación de Participación Ciudadana y Gobierno Abierto
|
Aplicación de Participación Ciudadana y Gobierno Abierto
|
||||||
|
|
||||||
[](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
[](https://travis-ci.org/consul/consul)
|
[](https://travis-ci.org/consul/consul)
|
||||||
[](https://codeclimate.com/github/consul/consul)
|
[](https://codeclimate.com/github/consul/consul)
|
||||||
[](https://gemnasium.com/consul/consul)
|
[](https://gemnasium.com/consul/consul)
|
||||||
[](https://coveralls.io/github/consul/consul?branch=master)
|
[](https://coveralls.io/github/consul/consul?branch=master)
|
||||||
|
[](http://www.gnu.org/licenses/agpl-3.0)
|
||||||
|
|
||||||
|
[](https://www.w3.org/WAI/eval/Overview)
|
||||||
|
[](https://rocketvalidator.com/opensource)
|
||||||
|
|
||||||
|
[](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
|
|
||||||
Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid.
|
Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid.
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,9 @@
|
|||||||
<glyph glyph-name="arrow-right" unicode="U" d="M329 256c0-5-2-9-5-13l-128-128c-4-3-8-5-13-5-5 0-9 2-13 5-4 4-5 8-5 13l0 256c0 5 1 9 5 13 4 3 8 5 13 5 5 0 9-2 13-5l128-128c3-4 5-8 5-13z"/>
|
<glyph glyph-name="arrow-right" unicode="U" d="M329 256c0-5-2-9-5-13l-128-128c-4-3-8-5-13-5-5 0-9 2-13 5-4 4-5 8-5 13l0 256c0 5 1 9 5 13 4 3 8 5 13 5 5 0 9-2 13-5l128-128c3-4 5-8 5-13z"/>
|
||||||
<glyph glyph-name="check-circle" unicode="V" d="M256 480c-124 0-224-100-224-224 0-124 100-224 224-224 124 0 224 100 224 224 0 124-100 224-224 224z m115-149l-139-179c-1-1-3-3-5-3-3 0-4 1-5 3-2 1-79 76-79 76l-2 1c0 1-1 2-1 3 0 2 1 3 1 4 1 0 1 0 1 1 8 8 24 24 25 25 1 2 2 3 4 3 3 0 5-2 6-3 1-1 45-43 45-43l111 143c1 0 2 1 4 1 1 0 2 0 3-1l31-24c0-1 1-3 1-4 0-1 0-2-1-3z"/>
|
<glyph glyph-name="check-circle" unicode="V" d="M256 480c-124 0-224-100-224-224 0-124 100-224 224-224 124 0 224 100 224 224 0 124-100 224-224 224z m115-149l-139-179c-1-1-3-3-5-3-3 0-4 1-5 3-2 1-79 76-79 76l-2 1c0 1-1 2-1 3 0 2 1 3 1 4 1 0 1 0 1 1 8 8 24 24 25 25 1 2 2 3 4 3 3 0 5-2 6-3 1-1 45-43 45-43l111 143c1 0 2 1 4 1 1 0 2 0 3-1l31-24c0-1 1-3 1-4 0-1 0-2-1-3z"/>
|
||||||
<glyph glyph-name="arrow-top" unicode="W" d="M402 165c0-5-2-10-5-13-4-4-8-6-13-6l-256 0c-5 0-9 2-13 6-3 3-5 8-5 13 0 5 2 9 5 12l128 128c4 4 8 6 13 6 5 0 9-2 13-6l128-128c3-3 5-7 5-12z"/>
|
<glyph glyph-name="arrow-top" unicode="W" d="M402 165c0-5-2-10-5-13-4-4-8-6-13-6l-256 0c-5 0-9 2-13 6-3 3-5 8-5 13 0 5 2 9 5 12l128 128c4 4 8 6 13 6 5 0 9-2 13-6l128-128c3-3 5-7 5-12z"/>
|
||||||
<glyph glyph-name="help-1" unicode="X" d="M345 435c-27 21-58 28-98 28-29 0-55-6-75-20-30-20-44-54-44-108l77 0c0 14-2 30 7 43 8 13 20 24 40 24 20 0 31-6 41-18 8-11 11-23 11-36 0-12-5-22-12-32-4-5-9-10-15-15 0 0-42-25-56-48-11-18-15-40-16-66 0-2 0-5 7-5 7 0 56 0 62 0 6 0 7 4 7 6 0 9 2 24 3 29 4 11 10 20 20 28l21 14c18 15 33 26 40 36 11 15 19 34 19 57 0 36-13 64-39 83z m-103-293c-26 1-47-17-48-46-1-28 19-46 45-47 27-1 48 17 49 45 1 28-19 47-46 48z"/>
|
|
||||||
<glyph glyph-name="checkmark-circle" unicode="Y" d="M171 296l-29-30 93-93 208 208-29 29-179-178z m251-40c0-92-74-166-166-166-92 0-166 74-166 166 0 92 74 166 166 166 16 0 31-2 46-6l32 32c-24 11-50 16-78 16-114 0-208-94-208-208 0-114 94-208 208-208 114 0 208 94 208 208z"/>
|
<glyph glyph-name="checkmark-circle" unicode="Y" d="M171 296l-29-30 93-93 208 208-29 29-179-178z m251-40c0-92-74-166-166-166-92 0-166 74-166 166 0 92 74 166 166 166 16 0 31-2 46-6l32 32c-24 11-50 16-78 16-114 0-208-94-208-208 0-114 94-208 208-208 114 0 208 94 208 208z"/>
|
||||||
|
<glyph glyph-name="minus-square" unicode="X" d="M357 402c17 0 32-6 45-18 12-13 19-28 19-46l0-201c0-17-7-32-19-45-13-13-28-19-45-19l-202 0c-17 0-32 6-45 19-12 13-19 28-19 45l0 201c0 18 7 33 19 46 13 12 28 18 45 18z m27-265l0 201c0 8-3 14-8 20-5 5-12 8-19 8l-202 0c-7 0-14-3-19-8-5-6-8-12-8-20l0-201c0-7 3-14 8-19 5-6 12-8 19-8l202 0c7 0 14 2 19 8 5 5 8 12 8 19z m-46 119c3 0 5-1 7-3 2-1 2-3 2-6l0-18c0-3 0-5-2-7-2-2-4-3-7-3l-164 0c-3 0-5 1-7 3-2 2-2 4-2 7l0 18c0 3 0 5 2 6 2 2 4 3 7 3z"/>
|
||||||
|
<glyph glyph-name="plus-square" unicode="Z" d="M347 247l0-18c0-3 0-5-2-7-2-2-4-3-7-3l-64 0 0-64c0-2-1-4-2-6-2-2-4-3-7-3l-18 0c-3 0-5 1-7 3-1 2-2 4-2 6l0 64-64 0c-3 0-5 1-7 3-2 2-2 4-2 7l0 18c0 3 0 5 2 6 2 2 4 3 7 3l64 0 0 64c0 3 1 5 2 7 2 1 4 2 7 2l18 0c3 0 5-1 7-2 1-2 2-4 2-7l0-64 64 0c3 0 5-1 7-3 2-1 2-3 2-6z m37-110l0 201c0 8-3 14-8 20-5 5-12 8-19 8l-202 0c-7 0-14-3-19-8-5-6-8-12-8-20l0-201c0-7 3-14 8-19 5-6 12-8 19-8l202 0c7 0 14 2 19 8 5 5 8 12 8 19z m37 201l0-201c0-17-7-32-19-45-13-13-28-19-45-19l-202 0c-17 0-32 6-45 19-12 13-19 28-19 45l0 201c0 18 7 33 19 46 13 12 28 18 45 18l202 0c17 0 32-6 45-18 12-13 19-28 19-46z"/>
|
||||||
|
<glyph glyph-name="expand" unicode="0" d="M26 168l-26-158c0-2 1-5 3-7 0 0 0 0 0 0 2-2 5-3 7-3l158 27c3 0 6 3 7 6 1 3 0 7-3 9l-30 31 82 82c4 4 4 9 0 13l-57 57c-3 3-9 3-12 0l-83-83-31 31c-2 2-5 3-9 2-3-1-5-4-6-7z m460 176l26 158c0 2-1 5-3 7 0 0 0 0 0 0-2 2-5 3-7 3l-158-27c-3 0-6-3-7-6-1-3 0-7 3-9l30-31-82-82c-4-4-4-9 0-13l57-57c3-3 9-3 12 0l83 83 31-31c2-2 5-3 9-2 3 1 5 4 6 7z"/>
|
||||||
|
<glyph glyph-name="telegram" unicode="1" d="M504 509c6-5 9-11 8-18l-73-439c-1-6-4-10-10-13-2-2-5-2-8-2-3 0-5 0-7 1l-130 53-69-84c-3-5-8-7-14-7-2 0-4 0-6 1-4 1-7 4-9 7-2 3-3 6-3 10l0 100 247 303-306-265-113 47c-7 2-10 7-11 15 0 8 3 14 9 17l476 274c2 2 5 3 9 3 4 0 7-1 10-3z"/>
|
||||||
</font></defs></svg>
|
</font></defs></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 28 KiB |
BIN
app/assets/images/more_info/budgets_en.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app/assets/images/more_info/budgets_es.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
app/assets/images/more_info/budgets_fr.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app/assets/images/more_info/budgets_pt-BR.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app/assets/images/more_info/debates.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/assets/images/more_info/proposals_en.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
app/assets/images/more_info/proposals_es.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
app/assets/images/more_info/proposals_fr.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
app/assets/images/more_info/proposals_pt-BR.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
@@ -12,8 +12,8 @@
|
|||||||
//
|
//
|
||||||
//= require jquery
|
//= require jquery
|
||||||
//= require jquery_ujs
|
//= require jquery_ujs
|
||||||
//= require jquery-ui/datepicker
|
//= require jquery-ui/widgets/datepicker
|
||||||
//= require jquery-ui/datepicker-es
|
//= require jquery-ui/i18n/datepicker-es
|
||||||
//= require foundation
|
//= require foundation
|
||||||
//= require turbolinks
|
//= require turbolinks
|
||||||
//= require ckeditor/loader
|
//= require ckeditor/loader
|
||||||
@@ -49,6 +49,7 @@
|
|||||||
//= require fixed_bar
|
//= require fixed_bar
|
||||||
//= require banners
|
//= require banners
|
||||||
//= require social_share
|
//= require social_share
|
||||||
|
//= require checkbox_toggle
|
||||||
//= require custom
|
//= require custom
|
||||||
|
|
||||||
var initialize_modules = function() {
|
var initialize_modules = function() {
|
||||||
@@ -74,6 +75,7 @@ var initialize_modules = function() {
|
|||||||
App.FixedBar.initialize();
|
App.FixedBar.initialize();
|
||||||
App.Banners.initialize();
|
App.Banners.initialize();
|
||||||
App.SocialShare.initialize();
|
App.SocialShare.initialize();
|
||||||
|
App.CheckboxToggle.initialize();
|
||||||
};
|
};
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|||||||
12
app/assets/javascripts/checkbox_toggle.js.coffee
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
App.CheckboxToggle =
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
$('[data-checkbox-toggle]').on 'change', ->
|
||||||
|
$this = $(this)
|
||||||
|
$target = $($this.data('checkbox-toggle'))
|
||||||
|
if $this.is(':checked')
|
||||||
|
$target.show()
|
||||||
|
else
|
||||||
|
$target.hide()
|
||||||
|
|
||||||
|
|
||||||
@@ -80,6 +80,7 @@ $budget: #7E328A;
|
|||||||
$budget-hover: #7571BF;
|
$budget-hover: #7571BF;
|
||||||
|
|
||||||
$highlight: #E7F2FC;
|
$highlight: #E7F2FC;
|
||||||
|
$light: #F5F7FA;
|
||||||
$featured: #FFDC5C;
|
$featured: #FFDC5C;
|
||||||
|
|
||||||
$footer-border: #BFC1C3;
|
$footer-border: #BFC1C3;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
// 03. List elements
|
// 03. List elements
|
||||||
// 04. Stats
|
// 04. Stats
|
||||||
// 05. Management
|
// 05. Management
|
||||||
|
// 06. Polls
|
||||||
//
|
//
|
||||||
|
|
||||||
// 01. Global styles
|
// 01. Global styles
|
||||||
@@ -20,6 +21,11 @@ body.admin {
|
|||||||
.top-links {
|
.top-links {
|
||||||
background: darken($admin-color, 15%);
|
background: darken($admin-color, 15%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.back-web {
|
||||||
|
padding-top: $line-height/4;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-bar {
|
.top-bar {
|
||||||
@@ -27,19 +33,37 @@ body.admin {
|
|||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-bar-title {
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
|
||||||
|
&.margin-top {
|
||||||
|
margin-top: $line-height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"], textarea {
|
input[type="text"], textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group input[type="text"] {
|
.fieldset {
|
||||||
border-radius: 0;
|
|
||||||
margin-bottom: 0 !important;
|
select {
|
||||||
|
height: $line-height*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input[type="text"] {
|
||||||
|
border-radius: 0;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +72,15 @@ body.admin {
|
|||||||
th {
|
th {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
|
&.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.text-right {
|
||||||
|
padding-right: $line-height;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
&.with-button {
|
&.with-button {
|
||||||
line-height: $line-height*2;
|
line-height: $line-height*2;
|
||||||
}
|
}
|
||||||
@@ -62,9 +95,20 @@ body.admin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.fixed {
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
input[type="submit"] ~ a, a ~ a {
|
input[type="submit"] ~ a, a ~ a {
|
||||||
margin-left: $line-height/2;
|
margin-left: 0;
|
||||||
margin-right: $line-height/2;
|
margin-right: 0;
|
||||||
|
margin-top: $line-height/2;
|
||||||
|
|
||||||
|
@include breakpoint(medium) {
|
||||||
|
margin-left: $line-height/2;
|
||||||
|
margin-right: $line-height/2;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +121,11 @@ body.admin {
|
|||||||
color: $admin-color;
|
color: $admin-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tabs-panel {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#proposals {
|
#proposals {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
@@ -148,6 +197,13 @@ body.admin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
|
||||||
|
.input-group-button {
|
||||||
|
padding-bottom: rem-calc(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 02. Sidebar
|
// 02. Sidebar
|
||||||
// -----------
|
// -----------
|
||||||
|
|
||||||
@@ -155,7 +211,7 @@ body.admin {
|
|||||||
border-right: 1px solid $border;
|
border-right: 1px solid $border;
|
||||||
|
|
||||||
@include breakpoint(medium) {
|
@include breakpoint(medium) {
|
||||||
padding-bottom: $line-height*3;
|
min-height: rem-calc(1100);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
@@ -165,10 +221,12 @@ body.admin {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
[class^="icon-"] {
|
[class^="icon-"] {
|
||||||
|
color: $admin-color;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: rem-calc(24);
|
font-size: rem-calc(24);
|
||||||
padding-right: rem-calc(12);
|
line-height: $line-height;
|
||||||
padding-top: rem-calc(4);
|
padding: $line-height/2 $line-height/4;
|
||||||
|
padding-left: 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,19 +235,26 @@ body.admin {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin-left: $line-height/1.5;
|
||||||
|
border-left: 1px solid $border;
|
||||||
|
padding-left: $line-height/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.section-title {
|
||||||
|
border-bottom: 1px solid $border;
|
||||||
|
}
|
||||||
|
|
||||||
&.active a {
|
&.active a {
|
||||||
background: #f3f6f7;
|
background: #f3f6f7;
|
||||||
|
border-radius: rem-calc(6);
|
||||||
|
-moz-border-radius: rem-calc(6);
|
||||||
|
-webkit-border-radius: rem-calc(6);
|
||||||
color: $admin-color;
|
color: $admin-color;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li.section {
|
|
||||||
border-bottom: 1px dotted #d5d5d5;
|
|
||||||
border-top: 1px dotted #d5d5d5;
|
|
||||||
height: $line-height/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
li a {
|
li a {
|
||||||
color: $text;
|
color: $text;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -199,10 +264,38 @@ body.admin {
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #f3f6f7;
|
background: #f3f6f7;
|
||||||
|
border-radius: rem-calc(6);
|
||||||
|
-moz-border-radius: rem-calc(6);
|
||||||
|
-webkit-border-radius: rem-calc(6);
|
||||||
|
color: $admin-color;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.is-accordion-submenu-parent {
|
||||||
|
|
||||||
|
& > a::after {
|
||||||
|
border-color: $admin-color transparent transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenu {
|
||||||
|
border-bottom: 0;
|
||||||
|
margin-left: $line-height;
|
||||||
|
|
||||||
|
li:first-child {
|
||||||
|
padding-top: $line-height/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
li:last-child {
|
||||||
|
padding-bottom: $line-height/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 03. List elements
|
// 03. List elements
|
||||||
@@ -403,3 +496,46 @@ table.investment-projects-summary {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.geozone {
|
||||||
|
background: #ececec;
|
||||||
|
border-radius: rem-calc(6);
|
||||||
|
color: $text;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: $small-font-size;
|
||||||
|
margin-bottom: $line-height/3;
|
||||||
|
padding: $line-height/4 $line-height/3;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #e0e0e0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 06. Polls
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
.count-error {
|
||||||
|
background: $alert-bg !important;
|
||||||
|
color: $color-alert;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
|
||||||
|
.callout {
|
||||||
|
height: $line-height*2;
|
||||||
|
line-height: $line-height*2;
|
||||||
|
padding: 0 $line-height/2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 07. CMS
|
||||||
|
// --------------
|
||||||
|
.cms_page_list {
|
||||||
|
|
||||||
|
[class^="icon-"] {
|
||||||
|
padding-right: $menu-icon-spacing;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
@import "admin";
|
@import "admin";
|
||||||
@import "layout";
|
@import "layout";
|
||||||
@import "participation";
|
@import "participation";
|
||||||
|
@import "pages";
|
||||||
@import "custom";
|
@import "custom";
|
||||||
@import "c3";
|
@import "c3";
|
||||||
@import "annotator.min";
|
@import "annotator.min";
|
||||||
|
|||||||
@@ -163,6 +163,12 @@
|
|||||||
.icon-whatsapp:before {
|
.icon-whatsapp:before {
|
||||||
content: "\50";
|
content: "\50";
|
||||||
}
|
}
|
||||||
|
.icon-zip:before {
|
||||||
|
content: "\4f";
|
||||||
|
}
|
||||||
|
.icon-banner:before {
|
||||||
|
content: "\51";
|
||||||
|
}
|
||||||
.icon-arrow-down:before {
|
.icon-arrow-down:before {
|
||||||
content: "\52";
|
content: "\52";
|
||||||
}
|
}
|
||||||
@@ -184,3 +190,6 @@
|
|||||||
.icon-checkmark-circle:before {
|
.icon-checkmark-circle:before {
|
||||||
content: "\59";
|
content: "\59";
|
||||||
}
|
}
|
||||||
|
.icon-telegram:before {
|
||||||
|
content: "\31";
|
||||||
|
}
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ a {
|
|||||||
padding-top: $line-height;
|
padding-top: $line-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.light {
|
||||||
|
background: $light;
|
||||||
|
}
|
||||||
|
|
||||||
.highlight {
|
.highlight {
|
||||||
background: $highlight;
|
background: $highlight;
|
||||||
}
|
}
|
||||||
@@ -204,6 +208,30 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu.vertical {
|
||||||
|
background: white;
|
||||||
|
margin: $line-height 0;
|
||||||
|
padding: $line-height;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $text-medium;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: $base-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-bottom: 2px solid $brand;
|
||||||
|
color: $brand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.small {
|
.small {
|
||||||
font-size: $small-font-size;
|
font-size: $small-font-size;
|
||||||
}
|
}
|
||||||
@@ -462,6 +490,7 @@ header {
|
|||||||
|
|
||||||
.input-group-button {
|
.input-group-button {
|
||||||
line-height: $line-height*1.5;
|
line-height: $line-height*1.5;
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background: $border;
|
background: $border;
|
||||||
@@ -483,7 +512,6 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.submenu {
|
.submenu {
|
||||||
background: white;
|
|
||||||
border-bottom: 1px solid $border;
|
border-bottom: 1px solid $border;
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: $line-height/2;
|
margin-bottom: $line-height/2;
|
||||||
@@ -585,7 +613,8 @@ footer {
|
|||||||
// 04. Tags
|
// 04. Tags
|
||||||
// --------
|
// --------
|
||||||
|
|
||||||
.tags a , .tag-cloud a, .categories a, .geozone a, .sidebar-links a {
|
.tags a , .tag-cloud a, .categories a, .geozone a, .sidebar-links a,
|
||||||
|
.tags span {
|
||||||
background: #ececec;
|
background: #ececec;
|
||||||
border-radius: rem-calc(6);
|
border-radius: rem-calc(6);
|
||||||
color: $text;
|
color: $text;
|
||||||
@@ -1104,11 +1133,12 @@ img.avatar, img.admin-avatar, img.moderator-avatar, img.initialjs-avatar {
|
|||||||
// --------------------
|
// --------------------
|
||||||
|
|
||||||
[class^="level-"] {
|
[class^="level-"] {
|
||||||
color: white;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-author {
|
.is-author {
|
||||||
background: #008CCF;
|
background: #00A5F1;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-association {
|
.is-association {
|
||||||
@@ -1166,7 +1196,11 @@ table {
|
|||||||
|
|
||||||
.button.button-twitter,
|
.button.button-twitter,
|
||||||
.button.button-facebook,
|
.button.button-facebook,
|
||||||
.button.button-google {
|
.button.button-google,
|
||||||
|
.button.button-telegram {
|
||||||
|
background: white;
|
||||||
|
color: $text;
|
||||||
|
font-weight: bold;
|
||||||
height: $line-height*2;
|
height: $line-height*2;
|
||||||
line-height: $line-height*2;
|
line-height: $line-height*2;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -1174,9 +1208,11 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button.button-twitter {
|
.button.button-twitter {
|
||||||
background: #45B0E3;
|
background: #ECF7FC;
|
||||||
|
border-left: 3px solid #45B0E3;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
|
color: #45B0E3;
|
||||||
content: "f";
|
content: "f";
|
||||||
font-family: "icons" !important;
|
font-family: "icons" !important;
|
||||||
font-size: rem-calc(24);
|
font-size: rem-calc(24);
|
||||||
@@ -1214,9 +1250,11 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button.button-facebook {
|
.button.button-facebook {
|
||||||
background: #3B5998;
|
background: #EBEEF4;
|
||||||
|
border-left: 3px solid #3B5998;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
|
color: #3B5998;
|
||||||
content: "A";
|
content: "A";
|
||||||
font-family: "icons" !important;
|
font-family: "icons" !important;
|
||||||
font-size: rem-calc(24);
|
font-size: rem-calc(24);
|
||||||
@@ -1254,9 +1292,11 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button.button-google {
|
.button.button-google {
|
||||||
background: #DE4C34;
|
background: #FCEDEA;
|
||||||
|
border-left: 3px solid #DE4C34;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
|
color: #DE4C34;
|
||||||
content: "B";
|
content: "B";
|
||||||
font-family: "icons" !important;
|
font-family: "icons" !important;
|
||||||
font-size: rem-calc(24);
|
font-size: rem-calc(24);
|
||||||
@@ -1293,6 +1333,48 @@ table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button.button-telegram {
|
||||||
|
background: #ECF7FC;
|
||||||
|
border-left: 3px solid #0088cc;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
color: #0088cc;
|
||||||
|
content: "1";
|
||||||
|
font-family: "icons" !important;
|
||||||
|
font-size: rem-calc(24);
|
||||||
|
left: 0;
|
||||||
|
line-height: $line-height*2;
|
||||||
|
padding: 0 rem-calc(20);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ssb-telegram {
|
||||||
|
background: #0088cc;
|
||||||
|
background-image: none !important;
|
||||||
|
color: white;
|
||||||
|
height: $line-height*2 !important;
|
||||||
|
position: relative;
|
||||||
|
width: $line-height*2 !important;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "1";
|
||||||
|
font-family: "icons" !important;
|
||||||
|
font-size: rem-calc(24);
|
||||||
|
left: 50%;
|
||||||
|
line-height: $line-height*2;
|
||||||
|
margin-left: rem-calc(-11);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
background: white;
|
||||||
|
color: #40A2D1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.social {
|
.social {
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -1384,6 +1466,30 @@ table {
|
|||||||
color: #CE3E26;
|
color: #CE3E26;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ssb-telegram {
|
||||||
|
background: #0088cc;
|
||||||
|
color: white;
|
||||||
|
height: $line-height;
|
||||||
|
position: relative;
|
||||||
|
width: $line-height*2;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "A";
|
||||||
|
font-family: "icons" !important;
|
||||||
|
font-size: rem-calc(24);
|
||||||
|
left: 50%;
|
||||||
|
line-height: $line-height*2;
|
||||||
|
margin-left: rem-calc(-11);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
background: white;
|
||||||
|
color: #40A2D1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13. Pages
|
// 13. Pages
|
||||||
|
|||||||
111
app/assets/stylesheets/pages.scss
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
// Table of Contents
|
||||||
|
//
|
||||||
|
// 01. Header
|
||||||
|
// 02. Navigation
|
||||||
|
// 03. Content
|
||||||
|
// 04. Sidebar
|
||||||
|
//
|
||||||
|
|
||||||
|
// 01. Header
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
.jumbo {
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
margin-top: rem-calc(-24);
|
||||||
|
padding-bottom: $line-height;
|
||||||
|
padding-top: $line-height;
|
||||||
|
|
||||||
|
&.light {
|
||||||
|
background: #ECF0F1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lead {
|
||||||
|
font-size: rem-calc(24);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 03. Navigation
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
.menu-pages {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
@include breakpoint(medium) {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: $line-height/2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 03. Content
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
.more-info-content {
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: $brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
.additional-info {
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not(.button) {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
font-size: $small-font-size;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.features {
|
||||||
|
list-style-type: circle;
|
||||||
|
margin-left: $line-height;
|
||||||
|
|
||||||
|
@include breakpoint(medium) {
|
||||||
|
margin: $line-height 0 $line-height $line-height*2.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: $line-height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-content {
|
||||||
|
border-top: 1px solid $medium-gray;
|
||||||
|
padding-bottom: $line-height*2;
|
||||||
|
padding-top: $line-height*2;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 04. Sidebar
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
.more-info-sidebar {
|
||||||
|
|
||||||
|
.sidebar-card {
|
||||||
|
border: 1px solid $border;
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
padding: $line-height/2;
|
||||||
|
|
||||||
|
&.light {
|
||||||
|
background: #ECF0F1;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,8 @@
|
|||||||
// 04. List participation
|
// 04. List participation
|
||||||
// 05. Featured
|
// 05. Featured
|
||||||
// 06. Budget
|
// 06. Budget
|
||||||
// 07. Proposals successfull
|
// 07. Proposals successful
|
||||||
|
// 08. Polls
|
||||||
//
|
//
|
||||||
|
|
||||||
// 01. Votes and supports
|
// 01. Votes and supports
|
||||||
@@ -297,7 +298,8 @@
|
|||||||
.debate-show,
|
.debate-show,
|
||||||
.proposal-show,
|
.proposal-show,
|
||||||
.investment-project-show,
|
.investment-project-show,
|
||||||
.budget-investment-show {
|
.budget-investment-show,
|
||||||
|
.polls-show {
|
||||||
|
|
||||||
p {
|
p {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
@@ -455,7 +457,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bullet {
|
.bullet {
|
||||||
color: $border;
|
color: $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.investment-project-show p, .budget-investment-show p {
|
.investment-project-show p, .budget-investment-show p {
|
||||||
@@ -769,7 +771,7 @@
|
|||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
.featured-debates, .featured-proposals,
|
.featured-debates, .featured-proposals,
|
||||||
.proposals-ballot, .proposals-ballot-list {
|
.enquiries-list {
|
||||||
padding: $line-height/2 0;
|
padding: $line-height/2 0;
|
||||||
|
|
||||||
@include breakpoint(medium) {
|
@include breakpoint(medium) {
|
||||||
@@ -974,6 +976,10 @@
|
|||||||
&.social-share-button-google_plus:hover {
|
&.social-share-button-google_plus:hover {
|
||||||
color: #CE3E26;
|
color: #CE3E26;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.social-share-button-telegram:hover {
|
||||||
|
color: #CE3E26;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1202,7 +1208,7 @@ ul.ballot-list {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 07. Proposals successfull
|
// 07. Proposals successful
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
.dark-heading {
|
.dark-heading {
|
||||||
@@ -1235,7 +1241,7 @@ ul.ballot-list {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.featured-proposals-ballot-banner {
|
.featured-proposals-ballot-banner, .sucessfull-proposals-banner {
|
||||||
background: #2D3E50 image-url("ballot_tiny.gif") no-repeat;
|
background: #2D3E50 image-url("ballot_tiny.gif") no-repeat;
|
||||||
background-position: 75% 0;
|
background-position: 75% 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -1259,10 +1265,10 @@ ul.ballot-list {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.featured-proposals-ballot-banner,
|
.sucessfull-proposals-banner,
|
||||||
.successfull .panel {
|
.successful .panel {
|
||||||
|
|
||||||
.icon-successfull {
|
.icon-successful {
|
||||||
border-right: 60px solid #FFD200;
|
border-right: 60px solid #FFD200;
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
border-bottom: 60px solid transparent;
|
border-bottom: 60px solid transparent;
|
||||||
@@ -1283,17 +1289,7 @@ ul.ballot-list {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.proposals-ballot-list {
|
.successful {
|
||||||
|
|
||||||
.proposal-sucessfull {
|
|
||||||
background: white;
|
|
||||||
border-top: 1px solid $border;
|
|
||||||
padding: $line-height 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.successfull {
|
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -1314,3 +1310,199 @@ ul.ballot-list {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 08. Polls
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
.dark-heading {
|
||||||
|
background: #2D3E50;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #92BA48;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: white;
|
||||||
|
color: $brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout {
|
||||||
|
|
||||||
|
&.warning a {
|
||||||
|
color: $color-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.primary a {
|
||||||
|
color: $color-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.alert a {
|
||||||
|
color: $color-alert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
background: #314253;
|
||||||
|
padding: $line-height;
|
||||||
|
|
||||||
|
@include breakpoint(medium) {
|
||||||
|
border-top: rem-calc(6) solid #92BA48;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not(.button) {
|
||||||
|
color: white;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back, .icon-angle-left {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.polls-show-header {
|
||||||
|
min-height: $line-height*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.poll, .poll-question {
|
||||||
|
background: white;
|
||||||
|
border-radius: rem-calc(6);
|
||||||
|
margin-bottom: $line-height/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.poll {
|
||||||
|
padding: $line-height;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.icon-poll-answer {
|
||||||
|
border-top: 0;
|
||||||
|
border-bottom: 60px solid transparent;
|
||||||
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 0;
|
||||||
|
|
||||||
|
&.can-answer:after,
|
||||||
|
&.cant-answer:after,
|
||||||
|
&.not-logged-in:after,
|
||||||
|
&.already-answer:after,
|
||||||
|
&.unverified:after {
|
||||||
|
font-family: "icons" !important;
|
||||||
|
left: 34px;
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.can-answer {
|
||||||
|
border-right: 60px solid $info-bg;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $color-info;
|
||||||
|
content: "\6c";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.cant-answer {
|
||||||
|
border-right: 60px solid $alert-bg;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $color-alert;
|
||||||
|
content: "\74";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.not-logged-in {
|
||||||
|
border-right: 60px solid $info-bg;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $color-info;
|
||||||
|
content: "\6f";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.unverified {
|
||||||
|
border-right: 60px solid $warning-bg;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $color-warning;
|
||||||
|
content: "\6f";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.already-answer {
|
||||||
|
border-right: 60px solid $success-bg;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $color-success;
|
||||||
|
content: "\59";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dates {
|
||||||
|
color: $text-medium;
|
||||||
|
font-size: $small-font-size;
|
||||||
|
margin-bottom: $line-height/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: rem-calc(30);
|
||||||
|
line-height: $line-height*1.5;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2.questions-callout {
|
||||||
|
font-size: $base-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3.section-title-divider {
|
||||||
|
border-bottom: 2px solid $brand;
|
||||||
|
color: $brand;
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.poll-question {
|
||||||
|
padding: 0 $line-height;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
padding-top: $line-height;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.poll-question-answers {
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-right: $line-height/4;
|
||||||
|
min-width: rem-calc(168);
|
||||||
|
|
||||||
|
&.answered {
|
||||||
|
background: #F4F8EC;
|
||||||
|
border: 2px solid #92BA48;
|
||||||
|
color: $text;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
background: #92BA48;
|
||||||
|
border-radius: rem-calc(20);
|
||||||
|
content: "\6c";
|
||||||
|
color: white;
|
||||||
|
font-family: "icons" !important;
|
||||||
|
font-size: rem-calc(12);
|
||||||
|
padding: $line-height/4;
|
||||||
|
position: absolute;
|
||||||
|
right: -6px;
|
||||||
|
top: -6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
66
app/controllers/admin/poll/booth_assignments_controller.rb
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
class Admin::Poll::BoothAssignmentsController < Admin::BaseController
|
||||||
|
|
||||||
|
before_action :load_poll, except: [:create, :destroy]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@booth_assignments = @poll.booth_assignments.includes(:booth).order('poll_booths.name').page(params[:page]).per(50)
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_booths
|
||||||
|
load_search
|
||||||
|
@booths = ::Poll::Booth.search(@search)
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@booth_assignment = @poll.booth_assignments.includes(:recounts, :final_recounts, :voters, officer_assignments: [officer: [:user]]).find(params[:id])
|
||||||
|
@voters_by_date = @booth_assignment.voters.group_by {|v| v.created_at.to_date}
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@booth_assignment = ::Poll::BoothAssignment.new(poll_id: booth_assignment_params[:poll_id], booth_id: booth_assignment_params[:booth_id])
|
||||||
|
|
||||||
|
if @booth_assignment.save
|
||||||
|
notice = t("admin.poll_booth_assignments.flash.create")
|
||||||
|
else
|
||||||
|
notice = t("admin.poll_booth_assignments.flash.error_create")
|
||||||
|
end
|
||||||
|
redirect_to admin_poll_booth_assignments_path(@booth_assignment.poll_id), notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@booth_assignment = ::Poll::BoothAssignment.find(params[:id])
|
||||||
|
|
||||||
|
if @booth_assignment.destroy
|
||||||
|
notice = t("admin.poll_booth_assignments.flash.destroy")
|
||||||
|
else
|
||||||
|
notice = t("admin.poll_booth_assignments.flash.error_destroy")
|
||||||
|
end
|
||||||
|
redirect_to admin_poll_booth_assignments_path(@booth_assignment.poll_id), notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_booth_assignment
|
||||||
|
@booth_assignment = ::Poll::BoothAssignment.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def booth_assignment_params
|
||||||
|
params.permit(:booth_id, :poll_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_poll
|
||||||
|
@poll = ::Poll.find(params[:poll_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
params.permit(:poll_id, :search)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_search
|
||||||
|
@search = search_params[:search]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
39
app/controllers/admin/poll/booths_controller.rb
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
class Admin::Poll::BoothsController < Admin::BaseController
|
||||||
|
load_and_authorize_resource class: 'Poll::Booth'
|
||||||
|
|
||||||
|
def index
|
||||||
|
@booths = @booths.order(name: :asc).page(params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
if @booth.save
|
||||||
|
redirect_to admin_booths_path, notice: t("flash.actions.create.poll_booth")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @booth.update(booth_params)
|
||||||
|
redirect_to admin_booth_path(@booth), notice: t("flash.actions.update.poll_booth")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def booth_params
|
||||||
|
params.require(:poll_booth).permit(:name, :location)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
92
app/controllers/admin/poll/officer_assignments_controller.rb
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
class Admin::Poll::OfficerAssignmentsController < Admin::BaseController
|
||||||
|
|
||||||
|
before_action :load_poll
|
||||||
|
before_action :redirect_if_blank_required_params, only: [:by_officer]
|
||||||
|
before_action :load_booth_assignment, only: [:create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@officers = ::Poll::Officer.
|
||||||
|
includes(:user).
|
||||||
|
order('users.username').
|
||||||
|
where(
|
||||||
|
id: @poll.officer_assignments.select(:officer_id).distinct.map(&:officer_id)
|
||||||
|
).page(params[:page]).per(50)
|
||||||
|
end
|
||||||
|
|
||||||
|
def by_officer
|
||||||
|
@poll = ::Poll.includes(:booths).find(params[:poll_id])
|
||||||
|
@officer = ::Poll::Officer.includes(:user).find(officer_assignment_params[:officer_id])
|
||||||
|
@officer_assignments = ::Poll::OfficerAssignment.
|
||||||
|
joins(:booth_assignment).
|
||||||
|
includes(:recount, :final_recounts, booth_assignment: :booth).
|
||||||
|
where("officer_id = ? AND poll_booth_assignments.poll_id = ?", @officer.id, @poll.id).
|
||||||
|
order(:date)
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_officers
|
||||||
|
load_search
|
||||||
|
@officers = User.joins(:poll_officer).search(@search).order(username: :asc)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@officer_assignment = ::Poll::OfficerAssignment.new(booth_assignment: @booth_assignment,
|
||||||
|
officer_id: create_params[:officer_id],
|
||||||
|
date: create_params[:date])
|
||||||
|
@officer_assignment.final = true if @officer_assignment.date > @booth_assignment.poll.ends_at.to_date
|
||||||
|
|
||||||
|
if @officer_assignment.save
|
||||||
|
notice = t("admin.poll_officer_assignments.flash.create")
|
||||||
|
else
|
||||||
|
notice = t("admin.poll_officer_assignments.flash.error_create")
|
||||||
|
end
|
||||||
|
redirect_to by_officer_admin_poll_officer_assignments_path(poll_id: create_params[:poll_id], officer_id: create_params[:officer_id]), notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@officer_assignment = ::Poll::OfficerAssignment.includes(:booth_assignment).find(params[:id])
|
||||||
|
|
||||||
|
if @officer_assignment.destroy
|
||||||
|
notice = t("admin.poll_officer_assignments.flash.destroy")
|
||||||
|
else
|
||||||
|
notice = t("admin.poll_officer_assignments.flash.error_destroy")
|
||||||
|
end
|
||||||
|
redirect_to by_officer_admin_poll_officer_assignments_path(poll_id: @officer_assignment.poll_id, officer_id: @officer_assignment.officer_id), notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def officer_assignment_params
|
||||||
|
params.permit(:officer_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_params
|
||||||
|
params.permit(:poll_id, :booth_id, :date, :officer_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_booth_assignment
|
||||||
|
@booth_assignment = ::Poll::BoothAssignment.includes(:poll).find_by(poll_id: create_params[:poll_id], booth_id: create_params[:booth_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_poll
|
||||||
|
@poll = ::Poll.find(params[:poll_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def redirect_if_blank_required_params
|
||||||
|
if officer_assignment_params[:officer_id].blank?
|
||||||
|
redirect_to admin_poll_path(@poll)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
params.permit(:poll_id, :search)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_search
|
||||||
|
@search = search_params[:search]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
39
app/controllers/admin/poll/officers_controller.rb
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
class Admin::Poll::OfficersController < Admin::BaseController
|
||||||
|
load_and_authorize_resource :officer, class: "Poll::Officer", except: [:edit, :show]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@officers = @officers.page(params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def search
|
||||||
|
@user = User.find_by(email: params[:email])
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
if @user
|
||||||
|
@officer = Poll::Officer.find_or_initialize_by(user: @user)
|
||||||
|
format.js
|
||||||
|
else
|
||||||
|
format.js { render "user_not_found" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@officer.user_id = params[:user_id]
|
||||||
|
@officer.save
|
||||||
|
|
||||||
|
redirect_to admin_officers_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@officer.destroy
|
||||||
|
redirect_to admin_officers_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
86
app/controllers/admin/poll/polls_controller.rb
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
class Admin::Poll::PollsController < Admin::BaseController
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
|
before_action :load_search, only: [:search_booths, :search_questions, :search_officers]
|
||||||
|
before_action :load_geozones, only: [:new, :create, :edit, :update]
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@poll = Poll.includes(:questions).
|
||||||
|
order('poll_questions.title').
|
||||||
|
find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
if @poll.save
|
||||||
|
redirect_to [:admin, @poll], notice: t("flash.actions.create.poll")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @poll.update(poll_params)
|
||||||
|
redirect_to [:admin, @poll], notice: t("flash.actions.update.poll")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_question
|
||||||
|
question = ::Poll::Question.find(params[:question_id])
|
||||||
|
|
||||||
|
if question.present?
|
||||||
|
@poll.questions << question
|
||||||
|
notice = t("admin.polls.flash.question_added")
|
||||||
|
else
|
||||||
|
notice = t("admin.polls.flash.error_on_question_added")
|
||||||
|
end
|
||||||
|
redirect_to admin_poll_path(@poll), notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_question
|
||||||
|
question = ::Poll::Question.find(params[:question_id])
|
||||||
|
|
||||||
|
if @poll.questions.include? question
|
||||||
|
@poll.questions.delete(question)
|
||||||
|
notice = t("admin.polls.flash.question_removed")
|
||||||
|
else
|
||||||
|
notice = t("admin.polls.flash.error_on_question_removed")
|
||||||
|
end
|
||||||
|
redirect_to admin_poll_path(@poll), notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_questions
|
||||||
|
@questions = ::Poll::Question.where("poll_id IS ? OR poll_id != ?", nil, @poll.id).search({search: @search}).order(title: :asc)
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def load_geozones
|
||||||
|
@geozones = Geozone.all.order(:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def poll_params
|
||||||
|
params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, geozone_ids: [])
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
params.permit(:poll_id, :search)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_search
|
||||||
|
@search = search_params[:search]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
64
app/controllers/admin/poll/questions_controller.rb
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
class Admin::Poll::QuestionsController < Admin::BaseController
|
||||||
|
load_and_authorize_resource :poll
|
||||||
|
load_and_authorize_resource :question, class: 'Poll::Question'
|
||||||
|
|
||||||
|
def index
|
||||||
|
@polls = Poll.all
|
||||||
|
@search = search_params[:search]
|
||||||
|
|
||||||
|
@questions = @questions.search(search_params).page(params[:page]).order("created_at DESC")
|
||||||
|
|
||||||
|
@proposals = Proposal.successful.sort_by_confidence_score
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@polls = Poll.all
|
||||||
|
@question.valid_answers = I18n.t('poll_questions.default_valid_answers')
|
||||||
|
proposal = Proposal.find(params[:proposal_id]) if params[:proposal_id].present?
|
||||||
|
@question.copy_attributes_from_proposal(proposal)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@question.author = @question.proposal.try(:author) || current_user
|
||||||
|
|
||||||
|
if @question.save
|
||||||
|
redirect_to admin_question_path(@question)
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @question.update(question_params)
|
||||||
|
redirect_to admin_question_path(@question), notice: t("flash.actions.save_changes.notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @question.destroy
|
||||||
|
notice = "Question destroyed succesfully"
|
||||||
|
else
|
||||||
|
notice = t("flash.actions.destroy.error")
|
||||||
|
end
|
||||||
|
redirect_to admin_questions_path, notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def question_params
|
||||||
|
params.require(:poll_question).permit(:poll_id, :title, :question, :description, :proposal_id, :valid_answers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
params.permit(:poll_id, :search)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
16
app/controllers/admin/poll/recounts_controller.rb
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
class Admin::Poll::RecountsController < Admin::BaseController
|
||||||
|
before_action :load_poll
|
||||||
|
|
||||||
|
def index
|
||||||
|
@booth_assignments = @poll.booth_assignments.
|
||||||
|
includes(:booth, :recounts, :final_recounts, :voters).
|
||||||
|
order("poll_booths.name").
|
||||||
|
page(params[:page]).per(50)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_poll
|
||||||
|
@poll = ::Poll.find(params[:poll_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
13
app/controllers/admin/poll/results_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class Admin::Poll::ResultsController < Admin::BaseController
|
||||||
|
before_action :load_poll
|
||||||
|
|
||||||
|
def index
|
||||||
|
@partial_results = @poll.partial_results
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_poll
|
||||||
|
@poll = ::Poll.includes(:questions).find(params[:poll_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
10
app/controllers/admin/site_customization/base_controller.rb
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
class Admin::SiteCustomization::BaseController < Admin::BaseController
|
||||||
|
helper_method :namespace
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def namespace
|
||||||
|
"admin"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
class Admin::SiteCustomization::ContentBlocksController < Admin::SiteCustomization::BaseController
|
||||||
|
load_and_authorize_resource :content_block, class: "SiteCustomization::ContentBlock"
|
||||||
|
|
||||||
|
def index
|
||||||
|
@content_blocks = SiteCustomization::ContentBlock.order(:name, :locale)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
if @content_block.save
|
||||||
|
redirect_to admin_site_customization_content_blocks_path, notice: t('admin.site_customization.content_blocks.create.notice')
|
||||||
|
else
|
||||||
|
flash.now[:error] = t('admin.site_customization.content_blocks.create.error')
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @content_block.update(content_block_params)
|
||||||
|
redirect_to admin_site_customization_content_blocks_path, notice: t('admin.site_customization.content_blocks.update.notice')
|
||||||
|
else
|
||||||
|
flash.now[:error] = t('admin.site_customization.content_blocks.update.error')
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@content_block.destroy
|
||||||
|
redirect_to admin_site_customization_content_blocks_path, notice: t('admin.site_customization.content_blocks.destroy.notice')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def content_block_params
|
||||||
|
params.require(:site_customization_content_block).permit(
|
||||||
|
:name,
|
||||||
|
:locale,
|
||||||
|
:body
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
class Admin::SiteCustomization::ImagesController < Admin::SiteCustomization::BaseController
|
||||||
|
load_and_authorize_resource :image, class: "SiteCustomization::Image"
|
||||||
|
|
||||||
|
def index
|
||||||
|
@images = SiteCustomization::Image.all_images
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if params[:site_customization_image].nil?
|
||||||
|
redirect_to admin_site_customization_images_path
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if @image.update(image_params)
|
||||||
|
redirect_to admin_site_customization_images_path, notice: t('admin.site_customization.images.update.notice')
|
||||||
|
else
|
||||||
|
flash.now[:error] = t('admin.site_customization.images.update.error')
|
||||||
|
|
||||||
|
@images = SiteCustomization::Image.all_images
|
||||||
|
idx = @images.index {|e| e.name == @image.name }
|
||||||
|
@images[idx] = @image
|
||||||
|
|
||||||
|
render :index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@image.image = nil
|
||||||
|
if @image.save
|
||||||
|
redirect_to admin_site_customization_images_path, notice: t('admin.site_customization.images.destroy.notice')
|
||||||
|
else
|
||||||
|
redirect_to admin_site_customization_images_path, notice: t('admin.site_customization.images.destroy.error')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def image_params
|
||||||
|
params.require(:site_customization_image).permit(
|
||||||
|
:image
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
44
app/controllers/admin/site_customization/pages_controller.rb
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
class Admin::SiteCustomization::PagesController < Admin::SiteCustomization::BaseController
|
||||||
|
load_and_authorize_resource :page, class: "SiteCustomization::Page"
|
||||||
|
|
||||||
|
def index
|
||||||
|
@pages = SiteCustomization::Page.order('slug').page(params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
if @page.save
|
||||||
|
redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.create.notice')
|
||||||
|
else
|
||||||
|
flash.now[:error] = t('admin.site_customization.pages.create.error')
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @page.update(page_params)
|
||||||
|
redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.update.notice')
|
||||||
|
else
|
||||||
|
flash.now[:error] = t('admin.site_customization.pages.update.error')
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@page.destroy
|
||||||
|
redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.destroy.notice')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def page_params
|
||||||
|
params.require(:site_customization_page).permit(
|
||||||
|
:slug,
|
||||||
|
:title,
|
||||||
|
:subtitle,
|
||||||
|
:content,
|
||||||
|
:more_info_flag,
|
||||||
|
:print_content_flag,
|
||||||
|
:status
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -129,16 +129,16 @@ module CommentableActions
|
|||||||
when '4'
|
when '4'
|
||||||
1.year.ago
|
1.year.ago
|
||||||
else
|
else
|
||||||
Date.parse(params[:advanced_search][:date_min]) rescue nil
|
Date.parse(params[:advanced_search][:date_min]) rescue 100.years.ago
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_finish_date
|
def search_finish_date
|
||||||
params[:advanced_search][:date_max].try(:to_date) || Date.today
|
(params[:advanced_search][:date_max].to_date rescue Date.today) || Date.today
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_date_range
|
def search_date_range
|
||||||
search_start_date.beginning_of_day..search_finish_date.end_of_day
|
[100.years.ago, search_start_date].max.beginning_of_day..[search_finish_date, Date.today].min.end_of_day
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_search_order
|
def set_search_order
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class DebatesController < ApplicationController
|
|||||||
|
|
||||||
def index_customization
|
def index_customization
|
||||||
@featured_debates = @debates.featured
|
@featured_debates = @debates.featured
|
||||||
@proposal_successfull_exists = Proposal.successfull.exists?
|
@proposal_successfull_exists = Proposal.successful.exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ class Management::BudgetsController < Management::BaseController
|
|||||||
|
|
||||||
def create_investments
|
def create_investments
|
||||||
@budgets = Budget.accepting.order(created_at: :desc).page(params[:page])
|
@budgets = Budget.accepting.order(created_at: :desc).page(params[:page])
|
||||||
|
|
||||||
|
if current_manager_administrator?
|
||||||
|
@budgets += Budget.reviewing.order(created_at: :desc) +
|
||||||
|
Budget.selecting.order(created_at: :desc)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def support_investments
|
def support_investments
|
||||||
@@ -23,4 +28,8 @@ class Management::BudgetsController < Management::BaseController
|
|||||||
check_verified_user t("management.budget_investments.alert.unverified_user")
|
check_verified_user t("management.budget_investments.alert.unverified_user")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def current_manager_administrator?
|
||||||
|
session[:manager]["login"].match("admin")
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class Management::UsersController < Management::BaseController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
params.require(:user).permit(:document_type, :document_number, :username, :email)
|
params.require(:user).permit(:document_type, :document_number, :username, :email, :date_of_birth)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy_session
|
def destroy_session
|
||||||
|
|||||||
12
app/controllers/officing/base_controller.rb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
class Officing::BaseController < ApplicationController
|
||||||
|
layout 'admin'
|
||||||
|
|
||||||
|
before_action :authenticate_user!
|
||||||
|
before_action :verify_officer
|
||||||
|
|
||||||
|
skip_authorization_check
|
||||||
|
|
||||||
|
def verify_officer
|
||||||
|
raise CanCan::AccessDenied unless current_user.try(:poll_officer?) || current_user.try(:administrator?)
|
||||||
|
end
|
||||||
|
end
|
||||||
6
app/controllers/officing/dashboard_controller.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class Officing::DashboardController < Officing::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
47
app/controllers/officing/final_recounts_controller.rb
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
class Officing::FinalRecountsController < Officing::BaseController
|
||||||
|
before_action :load_poll
|
||||||
|
before_action :load_officer_assignment, only: :create
|
||||||
|
|
||||||
|
def new
|
||||||
|
@officer_assignments = ::Poll::OfficerAssignment.
|
||||||
|
includes(:final_recounts, booth_assignment: [:booth]).
|
||||||
|
joins(:booth_assignment).
|
||||||
|
final.
|
||||||
|
where(id: current_user.poll_officer.officer_assignment_ids).
|
||||||
|
where("poll_booth_assignments.poll_id = ?", @poll.id).
|
||||||
|
order(date: :asc)
|
||||||
|
|
||||||
|
@final_recounts = @officer_assignments.select {|oa| oa.final_recounts.any?}.map(&:final_recounts).flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@final_recount = ::Poll::FinalRecount.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id, date: final_recount_params[:date])
|
||||||
|
@final_recount.officer_assignment_id = @officer_assignment.id
|
||||||
|
@final_recount.count = final_recount_params[:count]
|
||||||
|
|
||||||
|
if @final_recount.save
|
||||||
|
msg = { notice: t("officing.final_recounts.flash.create") }
|
||||||
|
else
|
||||||
|
msg = { alert: t("officing.final_recounts.flash.error_create") }
|
||||||
|
end
|
||||||
|
redirect_to new_officing_poll_final_recount_path(@poll), msg
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def load_poll
|
||||||
|
@poll = Poll.expired.find(params[:poll_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_officer_assignment
|
||||||
|
@officer_assignment = current_user.poll_officer.
|
||||||
|
officer_assignments.final.find_by(id: final_recount_params[:officer_assignment_id])
|
||||||
|
if @officer_assignment.blank?
|
||||||
|
redirect_to new_officing_poll_final_recount_path(@poll), alert: t("officing.final_recounts.flash.error_create")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def final_recount_params
|
||||||
|
params.permit(:officer_assignment_id, :count, :date)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
15
app/controllers/officing/polls_controller.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class Officing::PollsController < Officing::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
@polls = current_user.poll_officer? ? current_user.poll_officer.voting_days_assigned_polls : []
|
||||||
|
@polls = @polls.select {|poll| poll.current?(Time.current) || poll.current?(1.day.ago)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def final
|
||||||
|
@polls = current_user.poll_officer? ? current_user.poll_officer.final_days_assigned_polls : []
|
||||||
|
return unless current_user.poll_officer?
|
||||||
|
|
||||||
|
@polls = @polls.select {|poll| poll.ends_at > 1.week.ago && poll.expired?}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
46
app/controllers/officing/recounts_controller.rb
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
class Officing::RecountsController < Officing::BaseController
|
||||||
|
before_action :load_poll
|
||||||
|
before_action :load_officer_assignment, only: :create
|
||||||
|
|
||||||
|
def new
|
||||||
|
@officer_assignments = ::Poll::OfficerAssignment.
|
||||||
|
includes(:recount, booth_assignment: :booth).
|
||||||
|
joins(:booth_assignment).
|
||||||
|
voting_days.
|
||||||
|
where(id: current_user.poll_officer.officer_assignment_ids).
|
||||||
|
where("poll_booth_assignments.poll_id = ?", @poll.id).
|
||||||
|
order(date: :asc)
|
||||||
|
@recounted = @officer_assignments.select {|oa| oa.recount.present?}.reverse
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@recount = ::Poll::Recount.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id, date: @officer_assignment.date)
|
||||||
|
@recount.officer_assignment_id = @officer_assignment.id
|
||||||
|
@recount.count = recount_params[:count]
|
||||||
|
|
||||||
|
if @recount.save
|
||||||
|
msg = { notice: t("officing.recounts.flash.create") }
|
||||||
|
else
|
||||||
|
msg = { alert: t("officing.recounts.flash.error_create") }
|
||||||
|
end
|
||||||
|
redirect_to new_officing_poll_recount_path(@poll), msg
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def load_poll
|
||||||
|
@poll = Poll.find(params[:poll_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_officer_assignment
|
||||||
|
@officer_assignment = current_user.poll_officer.
|
||||||
|
officer_assignments.find_by(id: recount_params[:officer_assignment_id])
|
||||||
|
if @officer_assignment.blank?
|
||||||
|
redirect_to new_officing_poll_recount_path(@poll), alert: t("officing.recounts.flash.error_create")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recount_params
|
||||||
|
params.permit(:officer_assignment_id, :count)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
37
app/controllers/officing/residence_controller.rb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
class Officing::ResidenceController < Officing::BaseController
|
||||||
|
|
||||||
|
before_action :load_officer_assignment
|
||||||
|
before_action :validate_officer_assignment, only: :create
|
||||||
|
|
||||||
|
def new
|
||||||
|
@residence = Officing::Residence.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@residence = Officing::Residence.new(residence_params.merge(officer: current_user.poll_officer))
|
||||||
|
if @residence.save
|
||||||
|
redirect_to new_officing_voter_path(id: @residence.user.id), notice: t("officing.residence.flash.create")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def residence_params
|
||||||
|
params.require(:residence).permit(:document_number, :document_type, :year_of_birth)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_officer_assignment
|
||||||
|
@officer_assignments = current_user.poll_officer.
|
||||||
|
officer_assignments.
|
||||||
|
voting_days.
|
||||||
|
where(date: Time.current.to_date)
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_officer_assignment
|
||||||
|
if @officer_assignments.blank?
|
||||||
|
redirect_to officing_root_path, notice: t("officing.residence.flash.not_allowed")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
141
app/controllers/officing/results_controller.rb
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
class Officing::ResultsController < Officing::BaseController
|
||||||
|
before_action :load_poll
|
||||||
|
|
||||||
|
before_action :load_officer_assignments, only: :new
|
||||||
|
before_action :load_partial_results, only: :new
|
||||||
|
|
||||||
|
before_action :load_officer_assignment, only: :create
|
||||||
|
before_action :check_booth_and_date, only: :create
|
||||||
|
before_action :build_results, only: :create
|
||||||
|
|
||||||
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@results.each { |result| result.save! }
|
||||||
|
|
||||||
|
notice = t("officing.results.flash.create")
|
||||||
|
redirect_to new_officing_poll_result_path(@poll), notice: notice
|
||||||
|
end
|
||||||
|
|
||||||
|
def index
|
||||||
|
@booth_assignment = ::Poll::BoothAssignment.includes(:booth).find(index_params[:booth_assignment_id])
|
||||||
|
if current_user.poll_officer.officer_assignments.final.
|
||||||
|
where(booth_assignment_id: @booth_assignment.id).exists?
|
||||||
|
|
||||||
|
@partial_results = ::Poll::PartialResult.includes(:question).
|
||||||
|
where(booth_assignment_id: index_params[:booth_assignment_id]).
|
||||||
|
where(date: index_params[:date])
|
||||||
|
@whites = ::Poll::WhiteResult.where(booth_assignment_id: @booth_assignment.id, date: index_params[:date]).sum(:amount)
|
||||||
|
@nulls = ::Poll::NullResult.where(booth_assignment_id: @booth_assignment.id, date: index_params[:date]).sum(:amount)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_booth_and_date
|
||||||
|
if @officer_assignment.blank?
|
||||||
|
go_back_to_new(t("officing.results.flash.error_wrong_booth"))
|
||||||
|
elsif results_params[:date].blank? ||
|
||||||
|
Date.parse(results_params[:date]) < @poll.starts_at.to_date ||
|
||||||
|
Date.parse(results_params[:date]) > @poll.ends_at.to_date
|
||||||
|
go_back_to_new(t("officing.results.flash.error_wrong_date"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_results
|
||||||
|
@results = []
|
||||||
|
|
||||||
|
params[:questions].each_pair do |question_id, results|
|
||||||
|
question = @poll.questions.find(question_id)
|
||||||
|
go_back_to_new if question.blank?
|
||||||
|
|
||||||
|
results.each_pair do |answer_index, count|
|
||||||
|
if count.present?
|
||||||
|
answer = question.valid_answers[answer_index.to_i]
|
||||||
|
go_back_to_new if question.blank?
|
||||||
|
|
||||||
|
partial_result = ::Poll::PartialResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||||
|
date: results_params[:date],
|
||||||
|
question_id: question_id,
|
||||||
|
answer: answer)
|
||||||
|
partial_result.officer_assignment_id = @officer_assignment.id
|
||||||
|
partial_result.amount = count.to_i
|
||||||
|
partial_result.author = current_user
|
||||||
|
partial_result.origin = 'booth'
|
||||||
|
@results << partial_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
build_white_results
|
||||||
|
build_null_results
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_white_results
|
||||||
|
if results_params[:whites].present?
|
||||||
|
white_result = ::Poll::WhiteResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||||
|
date: results_params[:date])
|
||||||
|
white_result.officer_assignment_id = @officer_assignment.id
|
||||||
|
white_result.amount = results_params[:whites].to_i
|
||||||
|
white_result.author = current_user
|
||||||
|
white_result.origin = 'booth'
|
||||||
|
@results << white_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_null_results
|
||||||
|
if results_params[:nulls].present?
|
||||||
|
null_result = ::Poll::NullResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||||
|
date: results_params[:date])
|
||||||
|
null_result.officer_assignment_id = @officer_assignment.id
|
||||||
|
null_result.amount = results_params[:nulls].to_i
|
||||||
|
null_result.author = current_user
|
||||||
|
null_result.origin = 'booth'
|
||||||
|
@results << null_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def go_back_to_new(alert = nil)
|
||||||
|
params[:d] = results_params[:date]
|
||||||
|
params[:oa] = results_params[:officer_assignment_id]
|
||||||
|
flash.now[:alert] = (alert || t("officing.results.flash.error_create"))
|
||||||
|
load_officer_assignments
|
||||||
|
load_partial_results
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_poll
|
||||||
|
@poll = ::Poll.expired.includes(:questions).find(params[:poll_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_officer_assignment
|
||||||
|
@officer_assignment = current_user.poll_officer.
|
||||||
|
officer_assignments.final.find_by(id: results_params[:officer_assignment_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_officer_assignments
|
||||||
|
@officer_assignments = ::Poll::OfficerAssignment.
|
||||||
|
includes(booth_assignment: [:booth]).
|
||||||
|
joins(:booth_assignment).
|
||||||
|
final.
|
||||||
|
where(id: current_user.poll_officer.officer_assignment_ids).
|
||||||
|
where("poll_booth_assignments.poll_id = ?", @poll.id).
|
||||||
|
order(date: :asc)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_partial_results
|
||||||
|
if @officer_assignments.present?
|
||||||
|
@partial_results = ::Poll::PartialResult.where(officer_assignment_id: @officer_assignments.map(&:id)).order(:booth_assignment_id, :date)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def results_params
|
||||||
|
params.permit(:officer_assignment_id, :date, :questions, :whites, :nulls)
|
||||||
|
end
|
||||||
|
|
||||||
|
def index_params
|
||||||
|
params.permit(:booth_assignment_id, :date)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
25
app/controllers/officing/voters_controller.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class Officing::VotersController < Officing::BaseController
|
||||||
|
respond_to :html, :js
|
||||||
|
|
||||||
|
def new
|
||||||
|
@user = User.find(params[:id])
|
||||||
|
@polls = Poll.answerable_by(@user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@poll = Poll.find(voter_params[:poll_id])
|
||||||
|
@user = User.find(voter_params[:user_id])
|
||||||
|
@voter = Poll::Voter.new(document_type: @user.document_type,
|
||||||
|
document_number: @user.document_number,
|
||||||
|
user: @user,
|
||||||
|
poll: @poll)
|
||||||
|
@voter.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def voter_params
|
||||||
|
params.require(:voter).permit(:poll_id, :user_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -2,7 +2,11 @@ class PagesController < ApplicationController
|
|||||||
skip_authorization_check
|
skip_authorization_check
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render action: params[:id]
|
if @custom_page = SiteCustomization::Page.published.find_by(slug: params[:id])
|
||||||
|
render action: :custom_page
|
||||||
|
else
|
||||||
|
render action: params[:id]
|
||||||
|
end
|
||||||
rescue ActionView::MissingTemplate
|
rescue ActionView::MissingTemplate
|
||||||
head 404
|
head 404
|
||||||
end
|
end
|
||||||
|
|||||||
27
app/controllers/polls/questions_controller.rb
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
class Polls::QuestionsController < ApplicationController
|
||||||
|
|
||||||
|
load_and_authorize_resource :poll
|
||||||
|
load_and_authorize_resource :question, class: 'Poll::Question'
|
||||||
|
|
||||||
|
has_orders %w{most_voted newest oldest}, only: :show
|
||||||
|
|
||||||
|
def show
|
||||||
|
@commentable = @question.proposal.present? ? @question.proposal : @question
|
||||||
|
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
|
||||||
|
set_comment_flags(@comment_tree.comments)
|
||||||
|
|
||||||
|
question_answer = @question.answers.where(author_id: current_user.try(:id)).first
|
||||||
|
@answers_by_question_id = {@question.id => question_answer.try(:answer)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def answer
|
||||||
|
answer = @question.answers.find_or_initialize_by(author: current_user)
|
||||||
|
|
||||||
|
answer.answer = params[:answer]
|
||||||
|
answer.save!
|
||||||
|
answer.record_voter_participation
|
||||||
|
|
||||||
|
@answers_by_question_id = {@question.id => params[:answer]}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
23
app/controllers/polls_controller.rb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
class PollsController < ApplicationController
|
||||||
|
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
|
has_filters %w{current expired incoming}
|
||||||
|
|
||||||
|
::Poll::Answer # trigger autoload
|
||||||
|
|
||||||
|
def index
|
||||||
|
@polls = @polls.send(@current_filter).includes(:geozones).sort_for_list.page(params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@questions = @poll.questions.for_render.sort_for_list
|
||||||
|
|
||||||
|
@answers_by_question_id = {}
|
||||||
|
poll_answers = ::Poll::Answer.by_question(@poll.question_ids).by_author(current_user.try(:id))
|
||||||
|
poll_answers.each do |answer|
|
||||||
|
@answers_by_question_id[answer.question_id] = answer.answer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
class ProposalBallotsController < ApplicationController
|
|
||||||
skip_authorization_check
|
|
||||||
|
|
||||||
def index
|
|
||||||
@proposal_ballots = Proposal.successfull.sort_by_confidence_score
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -28,8 +28,8 @@ class ProposalsController < ApplicationController
|
|||||||
def index_customization
|
def index_customization
|
||||||
discard_archived
|
discard_archived
|
||||||
load_retired
|
load_retired
|
||||||
load_proposal_ballots
|
load_successful_proposals
|
||||||
load_featured unless @proposal_successfull_exists
|
load_featured unless @proposal_successful_exists
|
||||||
end
|
end
|
||||||
|
|
||||||
def vote
|
def vote
|
||||||
@@ -103,8 +103,8 @@ class ProposalsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_proposal_ballots
|
def load_successful_proposals
|
||||||
@proposal_successfull_exists = Proposal.successfull.exists?
|
@proposal_successful_exists = Proposal.successful.exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController
|
|||||||
@investment.send_unfeasible_email
|
@investment.send_unfeasible_email
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Activity.log(current_user, :valuate, @investment)
|
||||||
redirect_to valuation_budget_budget_investment_path(@budget, @investment), notice: t('valuation.budget_investments.notice.valuate')
|
redirect_to valuation_budget_budget_investment_path(@budget, @investment), notice: t('valuation.budget_investments.notice.valuate')
|
||||||
else
|
else
|
||||||
render action: :edit
|
render action: :edit
|
||||||
|
|||||||
@@ -4,6 +4,38 @@ module AdminHelper
|
|||||||
render "/#{namespace}/menu"
|
render "/#{namespace}/menu"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def namespaced_root_path
|
||||||
|
"/#{namespace}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def namespaced_header_title
|
||||||
|
t("#{namespace}.header.title")
|
||||||
|
end
|
||||||
|
|
||||||
|
def menu_tags?
|
||||||
|
["tags"].include? controller_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def menu_moderated_content?
|
||||||
|
["proposals", "debates", "comments", "users"].include? controller_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def menu_budget?
|
||||||
|
["spending_proposals"].include? controller_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def menu_polls?
|
||||||
|
["polls", "questions", "officers", "booths", "officer_assignments", "booth_assignments", "recounts", "results"].include? controller_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def menu_profiles?
|
||||||
|
["organizations", "officials", "moderators", "valuators", "managers"].include? controller_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def menu_banners?
|
||||||
|
["banners"].include? controller_name
|
||||||
|
end
|
||||||
|
|
||||||
def official_level_options
|
def official_level_options
|
||||||
options = [["", 0]]
|
options = [["", 0]]
|
||||||
(1..5).each do |i|
|
(1..5).each do |i|
|
||||||
@@ -16,10 +48,14 @@ module AdminHelper
|
|||||||
Administrator.all.order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] }
|
Administrator.all.order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def admin_submit_action(resource)
|
||||||
|
resource.persisted? ? "edit" : "new"
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def namespace
|
def namespace
|
||||||
controller.class.parent.name.downcase
|
controller.class.parent.name.downcase.gsub("::", "/")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -47,4 +47,12 @@ module ApplicationHelper
|
|||||||
"<span class='icon-angle-left'></span>".html_safe + t("shared.back")
|
"<span class='icon-angle-left'></span>".html_safe + t("shared.back")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def image_path_for(filename)
|
||||||
|
SiteCustomization::Image.image_path_for(filename) || filename
|
||||||
|
end
|
||||||
|
|
||||||
|
def content_block(name, locale)
|
||||||
|
SiteCustomization::ContentBlock.block_for(name, locale)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ module BudgetsHelper
|
|||||||
|
|
||||||
def namespaced_budget_investment_path(investment, options={})
|
def namespaced_budget_investment_path(investment, options={})
|
||||||
case namespace
|
case namespace
|
||||||
when "management::budgets"
|
when "management/budgets"
|
||||||
management_budget_investment_path(investment.budget, investment, options)
|
management_budget_investment_path(investment.budget, investment, options)
|
||||||
else
|
else
|
||||||
budget_investment_path(investment.budget, investment, options)
|
budget_investment_path(investment.budget, investment, options)
|
||||||
@@ -19,7 +19,7 @@ module BudgetsHelper
|
|||||||
|
|
||||||
def namespaced_budget_investment_vote_path(investment, options={})
|
def namespaced_budget_investment_vote_path(investment, options={})
|
||||||
case namespace
|
case namespace
|
||||||
when "management::budgets"
|
when "management/budgets"
|
||||||
vote_management_budget_investment_path(investment.budget, investment, options)
|
vote_management_budget_investment_path(investment.budget, investment, options)
|
||||||
else
|
else
|
||||||
vote_budget_investment_path(investment.budget, investment, options)
|
vote_budget_investment_path(investment.budget, investment, options)
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ module CommentsHelper
|
|||||||
def commentable_path(comment)
|
def commentable_path(comment)
|
||||||
if comment.commentable_type == "Budget::Investment"
|
if comment.commentable_type == "Budget::Investment"
|
||||||
budget_investment_path(comment.commentable.budget_id, comment.commentable)
|
budget_investment_path(comment.commentable.budget_id, comment.commentable)
|
||||||
|
elsif comment.commentable_type == "Poll::Question"
|
||||||
|
question_path(comment.commentable)
|
||||||
else
|
else
|
||||||
comment.commentable
|
comment.commentable
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ module EmbedVideosHelper
|
|||||||
|
|
||||||
def embedded_video_code
|
def embedded_video_code
|
||||||
link = @proposal.video_url
|
link = @proposal.video_url
|
||||||
|
title = t('proposals.show.embed_video_title', proposal: @proposal.title)
|
||||||
if link.match(/vimeo.*/)
|
if link.match(/vimeo.*/)
|
||||||
server = "Vimeo"
|
server = "Vimeo"
|
||||||
elsif link.match(/youtu*.*/)
|
elsif link.match(/youtu*.*/)
|
||||||
@@ -21,7 +22,7 @@ module EmbedVideosHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
if match and match[2]
|
if match and match[2]
|
||||||
'<iframe src="' + src + match[2] + '" frameborder="0" allowfullscreen></iframe>'
|
'<iframe src="' + src + match[2] + '" style="border:0;" allowfullscreen title="' + title + '"></iframe>'
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
end
|
end
|
||||||
|
|||||||
7
app/helpers/officers_helper.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
module OfficersHelper
|
||||||
|
|
||||||
|
def officer_label(officer)
|
||||||
|
truncate([officer.name, officer.email].compact.join(' - '), length: 100)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
36
app/helpers/officing_helper.rb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
module OfficingHelper
|
||||||
|
|
||||||
|
def officer_assignments_select_options(officer_assignments)
|
||||||
|
options = []
|
||||||
|
officer_assignments.each do |oa|
|
||||||
|
options << ["#{oa.booth_assignment.booth.name}: #{l(oa.date.to_date, format: :long)}", oa.id]
|
||||||
|
end
|
||||||
|
options_for_select(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def booths_for_officer_select_options(officer_assignments)
|
||||||
|
options = []
|
||||||
|
officer_assignments.each do |oa|
|
||||||
|
options << ["#{oa.booth_assignment.booth.name}", oa.id]
|
||||||
|
end
|
||||||
|
options.sort! {|x,y| x[0]<=>y[0]}
|
||||||
|
options_for_select(options, params[:oa])
|
||||||
|
end
|
||||||
|
|
||||||
|
def recount_to_compare_with_final_recount(final_recount)
|
||||||
|
recount = final_recount.booth_assignment.recounts.select {|r| r.date == final_recount.date}.first
|
||||||
|
recount.present? ? recount.count : "-"
|
||||||
|
end
|
||||||
|
|
||||||
|
def system_recount_to_compare_with_final_recount(final_recount)
|
||||||
|
final_recount.booth_assignment.voters.select {|v| v.created_at.to_date == final_recount.date}.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def answer_result_value(question_id, answer_index)
|
||||||
|
return nil if params.blank?
|
||||||
|
return nil if params[:questions].blank?
|
||||||
|
return nil if params[:questions][question_id.to_s].blank?
|
||||||
|
params[:questions][question_id.to_s][answer_index.to_s]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
7
app/helpers/poll_final_recounts_helper.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
module PollFinalRecountsHelper
|
||||||
|
|
||||||
|
def final_recount_for_date(final_recounts, date)
|
||||||
|
final_recounts.select {|f| f.date == date}.first
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
15
app/helpers/poll_recounts_helper.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
module PollRecountsHelper
|
||||||
|
|
||||||
|
def recount_for_date(recounts, date)
|
||||||
|
recounts.select {|r| r.date == date}.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def booth_assignment_sum_recounts(ba)
|
||||||
|
ba.recounts.any? ? ba.recounts.to_a.sum(&:count) : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def booth_assignment_sum_final_recounts(ba)
|
||||||
|
ba.final_recounts.any? ? ba.final_recounts.to_a.sum(&:count) :nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
49
app/helpers/polls_helper.rb
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
module PollsHelper
|
||||||
|
|
||||||
|
def poll_select_options(include_all=nil)
|
||||||
|
options = @polls.collect {|poll|
|
||||||
|
[poll.name, current_path_with_query_params(poll_id: poll.id)]
|
||||||
|
}
|
||||||
|
options << all_polls if include_all
|
||||||
|
options_for_select(options, request.fullpath)
|
||||||
|
end
|
||||||
|
|
||||||
|
def all_polls
|
||||||
|
[I18n.t("polls.all"), admin_questions_path]
|
||||||
|
end
|
||||||
|
|
||||||
|
def poll_dates(poll)
|
||||||
|
if poll.starts_at.blank? || poll.ends_at.blank?
|
||||||
|
I18n.t("polls.no_dates")
|
||||||
|
else
|
||||||
|
I18n.t("polls.dates", open_at: l(poll.starts_at.to_date), closed_at: l(poll.ends_at.to_date))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def poll_dates_select_options(poll)
|
||||||
|
options = []
|
||||||
|
(poll.starts_at.to_date..poll.ends_at.to_date).each do |date|
|
||||||
|
options << [l(date, format: :long), l(date)]
|
||||||
|
end
|
||||||
|
options_for_select(options, params[:d])
|
||||||
|
end
|
||||||
|
|
||||||
|
def poll_final_recount_option(poll)
|
||||||
|
final_date = poll.ends_at.to_date + 1.day
|
||||||
|
options_for_select([[I18n.t("polls.final_date"), l(final_date)]])
|
||||||
|
end
|
||||||
|
|
||||||
|
def poll_booths_select_options(poll)
|
||||||
|
options = []
|
||||||
|
poll.booths.each do |booth|
|
||||||
|
options << [booth_name_with_location(booth), booth.id]
|
||||||
|
end
|
||||||
|
options_for_select(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def booth_name_with_location(booth)
|
||||||
|
location = booth.location.blank? ? "" : " (#{booth.location})"
|
||||||
|
booth.name + location
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -2,7 +2,7 @@ module SignatureSheetsHelper
|
|||||||
|
|
||||||
def signable_options
|
def signable_options
|
||||||
[[t("activerecord.models.proposal", count: 1), Proposal],
|
[[t("activerecord.models.proposal", count: 1), Proposal],
|
||||||
[t("activerecord.models.spending_proposal", count: 1), SpendingProposal]]
|
[t("activerecord.models.budget/investment", count: 1), Budget::Investment]]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -32,7 +32,7 @@ module Abilities
|
|||||||
can :mark_featured, Debate
|
can :mark_featured, Debate
|
||||||
can :unmark_featured, Debate
|
can :unmark_featured, Debate
|
||||||
|
|
||||||
can :comment_as_administrator, [Debate, Comment, Proposal, Budget::Investment]
|
can :comment_as_administrator, [Debate, Comment, Proposal, Poll::Question, Budget::Investment]
|
||||||
|
|
||||||
can [:search, :create, :index, :destroy], ::Moderator
|
can [:search, :create, :index, :destroy], ::Moderator
|
||||||
can [:search, :create, :index, :summary], ::Valuator
|
can [:search, :create, :index, :summary], ::Valuator
|
||||||
@@ -50,7 +50,20 @@ module Abilities
|
|||||||
can :create, Budget::ValuatorAssignment
|
can :create, Budget::ValuatorAssignment
|
||||||
|
|
||||||
can [:search, :edit, :update, :create, :index, :destroy], Banner
|
can [:search, :edit, :update, :create, :index, :destroy], Banner
|
||||||
|
|
||||||
can [:index, :create, :edit, :update, :destroy], Geozone
|
can [:index, :create, :edit, :update, :destroy], Geozone
|
||||||
|
|
||||||
|
can [:read, :create, :update, :destroy, :add_question, :remove_question, :search_booths, :search_questions, :search_officers], Poll
|
||||||
|
can [:read, :create, :update, :destroy], Poll::Booth
|
||||||
|
can [:search, :create, :index, :destroy], ::Poll::Officer
|
||||||
|
can [:create, :destroy], ::Poll::BoothAssignment
|
||||||
|
can [:create, :destroy], ::Poll::OfficerAssignment
|
||||||
|
can [:read, :create, :update], Poll::Question
|
||||||
|
can :destroy, Poll::Question # , comments_count: 0, votes_up: 0
|
||||||
|
|
||||||
|
can :manage, SiteCustomization::Page
|
||||||
|
can :manage, SiteCustomization::Image
|
||||||
|
can :manage, SiteCustomization::ContentBlock
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ module Abilities
|
|||||||
|
|
||||||
can :create, DirectMessage
|
can :create, DirectMessage
|
||||||
can :show, DirectMessage, sender_id: user.id
|
can :show, DirectMessage, sender_id: user.id
|
||||||
|
can :answer, Poll do |poll|
|
||||||
|
poll.answerable_by?(user)
|
||||||
|
end
|
||||||
|
can :answer, Poll::Question do |question|
|
||||||
|
question.answerable_by?(user)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
can [:create, :show], ProposalNotification, proposal: { author_id: user.id }
|
can [:create, :show], ProposalNotification, proposal: { author_id: user.id }
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ module Abilities
|
|||||||
can [:read, :map], Debate
|
can [:read, :map], Debate
|
||||||
can [:read, :map, :summary], Proposal
|
can [:read, :map, :summary], Proposal
|
||||||
can :read, Comment
|
can :read, Comment
|
||||||
|
can :read, Poll
|
||||||
|
can :read, Poll::Question
|
||||||
can [:read, :welcome], Budget
|
can [:read, :welcome], Budget
|
||||||
can :read, Budget::Investment
|
can :read, Budget::Investment
|
||||||
can :read, SpendingProposal
|
can :read, SpendingProposal
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ module Abilities
|
|||||||
def initialize(user)
|
def initialize(user)
|
||||||
self.merge Abilities::Moderation.new(user)
|
self.merge Abilities::Moderation.new(user)
|
||||||
|
|
||||||
can :comment_as_moderator, [Debate, Comment, Proposal, Budget::Investment]
|
can :comment_as_moderator, [Debate, Comment, Proposal, Budget::Investment, Poll::Question]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class Activity < ActiveRecord::Base
|
|||||||
belongs_to :actionable, -> { with_hidden }, polymorphic: true
|
belongs_to :actionable, -> { with_hidden }, polymorphic: true
|
||||||
belongs_to :user, -> { with_hidden }
|
belongs_to :user, -> { with_hidden }
|
||||||
|
|
||||||
VALID_ACTIONS = %w( hide block restore )
|
VALID_ACTIONS = %w( hide block restore valuate )
|
||||||
|
|
||||||
validates :action, inclusion: {in: VALID_ACTIONS}
|
validates :action, inclusion: {in: VALID_ACTIONS}
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ class Activity < ActiveRecord::Base
|
|||||||
scope :on_debates, -> { where(actionable_type: 'Debate') }
|
scope :on_debates, -> { where(actionable_type: 'Debate') }
|
||||||
scope :on_users, -> { where(actionable_type: 'User') }
|
scope :on_users, -> { where(actionable_type: 'User') }
|
||||||
scope :on_comments, -> { where(actionable_type: 'Comment') }
|
scope :on_comments, -> { where(actionable_type: 'Comment') }
|
||||||
|
scope :on_budget_investments, -> { where(actionable_type: 'Budget::Investment') }
|
||||||
scope :for_render, -> { includes(user: [:moderator, :administrator]).includes(:actionable) }
|
scope :for_render, -> { includes(user: [:moderator, :administrator]).includes(:actionable) }
|
||||||
|
|
||||||
def self.log(user, action, actionable)
|
def self.log(user, action, actionable)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class Budget
|
|||||||
validates :description, presence: true
|
validates :description, presence: true
|
||||||
validates :heading_id, presence: true
|
validates :heading_id, presence: true
|
||||||
validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required?
|
validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required?
|
||||||
|
validates_presence_of :price, if: :price_required?
|
||||||
|
|
||||||
validates :title, length: { in: 4..Budget::Investment.title_max_length }
|
validates :title, length: { in: 4..Budget::Investment.title_max_length }
|
||||||
validates :description, length: { maximum: Budget::Investment.description_max_length }
|
validates :description, length: { maximum: Budget::Investment.description_max_length }
|
||||||
@@ -136,6 +137,10 @@ class Budget
|
|||||||
unfeasible? && valuation_finished?
|
unfeasible? && valuation_finished?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def price_required?
|
||||||
|
feasible? && valuation_finished?
|
||||||
|
end
|
||||||
|
|
||||||
def unfeasible_email_pending?
|
def unfeasible_email_pending?
|
||||||
unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished?
|
unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished?
|
||||||
end
|
end
|
||||||
@@ -225,7 +230,7 @@ class Budget
|
|||||||
def should_show_aside?
|
def should_show_aside?
|
||||||
(budget.selecting? && !unfeasible?) ||
|
(budget.selecting? && !unfeasible?) ||
|
||||||
(budget.balloting? && feasible?) ||
|
(budget.balloting? && feasible?) ||
|
||||||
(budget.valuating? && feasible?)
|
(budget.valuating? && !unfeasible?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def should_show_votes?
|
def should_show_votes?
|
||||||
@@ -259,7 +264,7 @@ class Budget
|
|||||||
private
|
private
|
||||||
|
|
||||||
def set_denormalized_ids
|
def set_denormalized_ids
|
||||||
self.group_id ||= self.heading.try(:group_id)
|
self.group_id = self.heading.try(:group_id) if self.heading_id_changed?
|
||||||
self.budget_id ||= self.heading.try(:group).try(:budget_id)
|
self.budget_id ||= self.heading.try(:group).try(:budget_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ class Comment < ActiveRecord::Base
|
|||||||
|
|
||||||
validates :body, presence: true
|
validates :body, presence: true
|
||||||
validates :user, presence: true
|
validates :user, presence: true
|
||||||
validates_inclusion_of :commentable_type, in: ["Debate", "Proposal", "Budget::Investment"]
|
|
||||||
|
validates_inclusion_of :commentable_type, in: ["Debate", "Proposal", "Budget::Investment", "Poll::Question"]
|
||||||
|
|
||||||
validate :validate_body_length
|
validate :validate_body_length
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ module Searchable
|
|||||||
},
|
},
|
||||||
ignoring: :accents,
|
ignoring: :accents,
|
||||||
ranked_by: '(:tsearch)',
|
ranked_by: '(:tsearch)',
|
||||||
order_within_rank: "#{self.table_name}.cached_votes_up DESC"
|
order_within_rank: (self.column_names.include?('cached_votes_up') ? "#{self.table_name}.cached_votes_up DESC" : nil)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
class FailedCensusCall < ActiveRecord::Base
|
class FailedCensusCall < ActiveRecord::Base
|
||||||
belongs_to :user, counter_cache: true
|
belongs_to :user, counter_cache: true
|
||||||
|
belongs_to :poll_officer, class_name: 'Poll::Officer', counter_cache: true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ class Geozone < ActiveRecord::Base
|
|||||||
Geozone.pluck(:name)
|
Geozone.pluck(:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.city
|
||||||
|
where(name: 'city').first
|
||||||
|
end
|
||||||
|
|
||||||
def safe_to_destroy?
|
def safe_to_destroy?
|
||||||
Geozone.reflect_on_all_associations(:has_many).all? do |association|
|
Geozone.reflect_on_all_associations(:has_many).all? do |association|
|
||||||
association.klass.where(geozone: self).empty?
|
association.klass.where(geozone: self).empty?
|
||||||
|
|||||||
126
app/models/officing/residence.rb
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
class Officing::Residence
|
||||||
|
include ActiveModel::Model
|
||||||
|
include ActiveModel::Validations::Callbacks
|
||||||
|
|
||||||
|
attr_accessor :user, :officer, :document_number, :document_type, :year_of_birth
|
||||||
|
|
||||||
|
before_validation :call_census_api
|
||||||
|
|
||||||
|
validates_presence_of :document_number
|
||||||
|
validates_presence_of :document_type
|
||||||
|
validates_presence_of :year_of_birth
|
||||||
|
|
||||||
|
validate :allowed_age
|
||||||
|
validate :residence_in_madrid
|
||||||
|
|
||||||
|
def initialize(attrs={})
|
||||||
|
super
|
||||||
|
clean_document_number
|
||||||
|
end
|
||||||
|
|
||||||
|
def save
|
||||||
|
return false unless valid?
|
||||||
|
|
||||||
|
if user_exists?
|
||||||
|
self.user = find_user_by_document
|
||||||
|
self.user.update(verified_at: Time.current)
|
||||||
|
else
|
||||||
|
user_params = {
|
||||||
|
document_number: document_number,
|
||||||
|
document_type: document_type,
|
||||||
|
geozone: self.geozone,
|
||||||
|
date_of_birth: date_of_birth.to_datetime,
|
||||||
|
gender: gender,
|
||||||
|
residence_verified_at: Time.current,
|
||||||
|
verified_at: Time.current,
|
||||||
|
erased_at: Time.current,
|
||||||
|
password: random_password,
|
||||||
|
terms_of_service: '1',
|
||||||
|
email: nil
|
||||||
|
}
|
||||||
|
self.user = User.create!(user_params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def store_failed_census_call
|
||||||
|
FailedCensusCall.create({
|
||||||
|
user: user,
|
||||||
|
document_number: document_number,
|
||||||
|
document_type: document_type,
|
||||||
|
year_of_birth: year_of_birth,
|
||||||
|
poll_officer: officer
|
||||||
|
})
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_exists?
|
||||||
|
find_user_by_document.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_user_by_document
|
||||||
|
User.where(document_number: document_number,
|
||||||
|
document_type: document_type).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def residence_in_madrid
|
||||||
|
return if errors.any?
|
||||||
|
|
||||||
|
unless residency_valid?
|
||||||
|
store_failed_census_call
|
||||||
|
errors.add(:residence_in_madrid, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def allowed_age
|
||||||
|
return if errors[:year_of_birth].any?
|
||||||
|
return unless @census_api_response.valid?
|
||||||
|
|
||||||
|
unless allowed_age?
|
||||||
|
errors.add(:year_of_birth, I18n.t('verification.residence.new.error_not_allowed_age'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def allowed_age?
|
||||||
|
Age.in_years(date_of_birth) >= User.minimum_required_age
|
||||||
|
end
|
||||||
|
|
||||||
|
def geozone
|
||||||
|
Geozone.where(census_code: district_code).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def district_code
|
||||||
|
@census_api_response.district_code
|
||||||
|
end
|
||||||
|
|
||||||
|
def gender
|
||||||
|
@census_api_response.gender
|
||||||
|
end
|
||||||
|
|
||||||
|
def date_of_birth
|
||||||
|
@census_api_response.date_of_birth
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def call_census_api
|
||||||
|
@census_api_response = CensusApi.new.call(document_type, document_number)
|
||||||
|
end
|
||||||
|
|
||||||
|
def residency_valid?
|
||||||
|
@census_api_response.valid? &&
|
||||||
|
@census_api_response.date_of_birth.year.to_s == year_of_birth.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def census_year_of_birth
|
||||||
|
@census_api_response.date_of_birth.year
|
||||||
|
end
|
||||||
|
|
||||||
|
def clean_document_number
|
||||||
|
self.document_number = self.document_number.gsub(/[^a-z0-9]+/i, "").upcase unless self.document_number.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
def random_password
|
||||||
|
(0...20).map { ('a'..'z').to_a[rand(26)] }.join
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
65
app/models/poll.rb
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
class Poll < ActiveRecord::Base
|
||||||
|
has_many :booth_assignments, class_name: "Poll::BoothAssignment"
|
||||||
|
has_many :booths, through: :booth_assignments
|
||||||
|
has_many :partial_results, through: :booth_assignments
|
||||||
|
has_many :white_results, through: :booth_assignments
|
||||||
|
has_many :null_results, through: :booth_assignments
|
||||||
|
has_many :voters
|
||||||
|
has_many :officer_assignments, through: :booth_assignments
|
||||||
|
has_many :officers, through: :officer_assignments
|
||||||
|
has_many :questions
|
||||||
|
|
||||||
|
has_and_belongs_to_many :geozones
|
||||||
|
|
||||||
|
validates :name, presence: true
|
||||||
|
|
||||||
|
validate :date_range
|
||||||
|
|
||||||
|
scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.current, Time.current) }
|
||||||
|
scope :incoming, -> { where('? < starts_at', Time.current) }
|
||||||
|
scope :expired, -> { where('ends_at < ?', Time.current) }
|
||||||
|
scope :published, -> { where('published = ?', true) }
|
||||||
|
scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) }
|
||||||
|
|
||||||
|
scope :sort_for_list, -> { order(:geozone_restricted, :starts_at, :name) }
|
||||||
|
|
||||||
|
def current?(timestamp = DateTime.current)
|
||||||
|
starts_at <= timestamp && timestamp <= ends_at
|
||||||
|
end
|
||||||
|
|
||||||
|
def incoming?(timestamp = DateTime.current)
|
||||||
|
timestamp < starts_at
|
||||||
|
end
|
||||||
|
|
||||||
|
def expired?(timestamp = DateTime.current)
|
||||||
|
ends_at < timestamp
|
||||||
|
end
|
||||||
|
|
||||||
|
def answerable_by?(user)
|
||||||
|
user.present? &&
|
||||||
|
user.level_two_or_three_verified? &&
|
||||||
|
current? &&
|
||||||
|
(!geozone_restricted || geozone_ids.include?(user.geozone_id))
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.answerable_by(user)
|
||||||
|
return none if user.nil? || user.unverified?
|
||||||
|
current.joins('LEFT JOIN "geozones_polls" ON "geozones_polls"."poll_id" = "polls"."id"')
|
||||||
|
.where('geozone_restricted = ? OR geozones_polls.geozone_id = ?', false, user.geozone_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def votable_by?(user)
|
||||||
|
!document_has_voted?(user.document_number, user.document_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
def document_has_voted?(document_number, document_type)
|
||||||
|
voters.where(document_number: document_number, document_type: document_type).exists?
|
||||||
|
end
|
||||||
|
|
||||||
|
def date_range
|
||||||
|
unless starts_at.present? && ends_at.present? && starts_at <= ends_at
|
||||||
|
errors.add(:starts_at, I18n.t('errors.messages.invalid_date_range'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
19
app/models/poll/answer.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
class Poll::Answer < ActiveRecord::Base
|
||||||
|
|
||||||
|
belongs_to :question, -> { with_hidden }
|
||||||
|
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||||
|
|
||||||
|
delegate :poll, :poll_id, to: :question
|
||||||
|
|
||||||
|
validates :question, presence: true
|
||||||
|
validates :author, presence: true
|
||||||
|
validates :answer, presence: true
|
||||||
|
validates :answer, inclusion: {in: ->(a) { a.question.valid_answers }}
|
||||||
|
|
||||||
|
scope :by_author, -> (author_id) { where(author_id: author_id) }
|
||||||
|
scope :by_question, -> (question_id) { where(question_id: question_id) }
|
||||||
|
|
||||||
|
def record_voter_participation
|
||||||
|
Poll::Voter.create!(user: author, poll: poll)
|
||||||
|
end
|
||||||
|
end
|
||||||
13
app/models/poll/booth.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class Poll
|
||||||
|
class Booth < ActiveRecord::Base
|
||||||
|
has_many :booth_assignments, class_name: "Poll::BoothAssignment"
|
||||||
|
has_many :polls, through: :booth_assignments
|
||||||
|
|
||||||
|
validates :name, presence: true, uniqueness: true
|
||||||
|
|
||||||
|
def self.search(terms)
|
||||||
|
return Booth.none if terms.blank?
|
||||||
|
Booth.where("name ILIKE ? OR location ILIKE ?", "%#{terms}%", "%#{terms}%")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
15
app/models/poll/booth_assignment.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class Poll
|
||||||
|
class BoothAssignment < ActiveRecord::Base
|
||||||
|
belongs_to :booth
|
||||||
|
belongs_to :poll
|
||||||
|
|
||||||
|
has_many :officer_assignments, class_name: "Poll::OfficerAssignment", dependent: :destroy
|
||||||
|
has_many :recounts, class_name: "Poll::Recount", dependent: :destroy
|
||||||
|
has_many :final_recounts, class_name: "Poll::FinalRecount", dependent: :destroy
|
||||||
|
has_many :officers, through: :officer_assignments
|
||||||
|
has_many :voters
|
||||||
|
has_many :partial_results
|
||||||
|
has_many :white_results
|
||||||
|
has_many :null_results
|
||||||
|
end
|
||||||
|
end
|
||||||
19
app/models/poll/final_recount.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
class Poll
|
||||||
|
class FinalRecount < ActiveRecord::Base
|
||||||
|
belongs_to :booth_assignment, class_name: "Poll::BoothAssignment"
|
||||||
|
belongs_to :officer_assignment, class_name: "Poll::OfficerAssignment"
|
||||||
|
|
||||||
|
validates :booth_assignment_id, presence: true
|
||||||
|
validates :date, presence: true, uniqueness: {scope: :booth_assignment_id}
|
||||||
|
validates :count, presence: true, numericality: {only_integer: true}
|
||||||
|
|
||||||
|
before_save :update_logs
|
||||||
|
|
||||||
|
def update_logs
|
||||||
|
if self.count_changed? && self.count_was.present?
|
||||||
|
self.count_log += ":#{self.count_was.to_s}"
|
||||||
|
self.officer_assignment_id_log += ":#{self.officer_assignment_id_was.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
23
app/models/poll/null_result.rb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
class Poll::NullResult < ActiveRecord::Base
|
||||||
|
|
||||||
|
VALID_ORIGINS = %w{ web booth }
|
||||||
|
|
||||||
|
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||||
|
belongs_to :booth_assignment
|
||||||
|
belongs_to :officer_assignment
|
||||||
|
|
||||||
|
validates :author, presence: true
|
||||||
|
validates :origin, inclusion: {in: VALID_ORIGINS}
|
||||||
|
|
||||||
|
scope :by_author, -> (author_id) { where(author_id: author_id) }
|
||||||
|
|
||||||
|
before_save :update_logs
|
||||||
|
|
||||||
|
def update_logs
|
||||||
|
if self.amount_changed? && self.amount_was.present?
|
||||||
|
self.amount_log += ":#{self.amount_was.to_s}"
|
||||||
|
self.officer_assignment_id_log += ":#{self.officer_assignment_id_was.to_s}"
|
||||||
|
self.author_id_log += ":#{self.author_id_was.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
26
app/models/poll/officer.rb
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
class Poll
|
||||||
|
class Officer < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
has_many :officer_assignments, class_name: "Poll::OfficerAssignment"
|
||||||
|
has_many :failed_census_calls, foreign_key: :poll_officer_id
|
||||||
|
|
||||||
|
validates :user_id, presence: true, uniqueness: true
|
||||||
|
|
||||||
|
delegate :name, :email, to: :user
|
||||||
|
|
||||||
|
def voting_days_assigned_polls
|
||||||
|
officer_assignments.voting_days.includes(booth_assignment: :poll).
|
||||||
|
map(&:booth_assignment).
|
||||||
|
map(&:poll).uniq.compact.
|
||||||
|
sort {|x, y| y.ends_at <=> x.ends_at}
|
||||||
|
end
|
||||||
|
|
||||||
|
def final_days_assigned_polls
|
||||||
|
officer_assignments.final.includes(booth_assignment: :poll).
|
||||||
|
map(&:booth_assignment).
|
||||||
|
map(&:poll).uniq.compact.
|
||||||
|
sort {|x, y| y.ends_at <=> x.ends_at}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
25
app/models/poll/officer_assignment.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class Poll
|
||||||
|
class OfficerAssignment < ActiveRecord::Base
|
||||||
|
belongs_to :officer
|
||||||
|
belongs_to :booth_assignment
|
||||||
|
has_one :recount
|
||||||
|
has_many :final_recounts
|
||||||
|
has_many :partial_results
|
||||||
|
has_many :voters
|
||||||
|
|
||||||
|
validates :officer_id, presence: true
|
||||||
|
validates :booth_assignment_id, presence: true
|
||||||
|
validates :date, presence: true, uniqueness: { scope: [:officer_id, :booth_assignment_id] }
|
||||||
|
|
||||||
|
delegate :poll_id, :booth_id, to: :booth_assignment
|
||||||
|
|
||||||
|
scope :voting_days, -> { where(final: false) }
|
||||||
|
scope :final, -> { where(final: true) }
|
||||||
|
|
||||||
|
before_create :log_user_data
|
||||||
|
|
||||||
|
def log_user_data
|
||||||
|
self.user_data_log = "#{officer.user_id} - #{officer.user.name_and_email}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
28
app/models/poll/partial_result.rb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
class Poll::PartialResult < ActiveRecord::Base
|
||||||
|
|
||||||
|
VALID_ORIGINS = %w{ web booth }
|
||||||
|
|
||||||
|
belongs_to :question, -> { with_hidden }
|
||||||
|
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||||
|
belongs_to :booth_assignment
|
||||||
|
belongs_to :officer_assignment
|
||||||
|
|
||||||
|
validates :question, presence: true
|
||||||
|
validates :author, presence: true
|
||||||
|
validates :answer, presence: true
|
||||||
|
validates :answer, inclusion: {in: ->(a) { a.question.valid_answers }}
|
||||||
|
validates :origin, inclusion: {in: VALID_ORIGINS}
|
||||||
|
|
||||||
|
scope :by_author, -> (author_id) { where(author_id: author_id) }
|
||||||
|
scope :by_question, -> (question_id) { where(question_id: question_id) }
|
||||||
|
|
||||||
|
before_save :update_logs
|
||||||
|
|
||||||
|
def update_logs
|
||||||
|
if self.amount_changed? && self.amount_was.present?
|
||||||
|
self.amount_log += ":#{self.amount_was.to_s}"
|
||||||
|
self.officer_assignment_id_log += ":#{self.officer_assignment_id_was.to_s}"
|
||||||
|
self.author_id_log += ":#{self.author_id_was.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
70
app/models/poll/question.rb
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
class Poll::Question < ActiveRecord::Base
|
||||||
|
include Measurable
|
||||||
|
include Searchable
|
||||||
|
|
||||||
|
acts_as_paranoid column: :hidden_at
|
||||||
|
include ActsAsParanoidAliases
|
||||||
|
|
||||||
|
belongs_to :poll
|
||||||
|
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||||
|
|
||||||
|
has_many :comments, as: :commentable
|
||||||
|
has_many :answers
|
||||||
|
has_many :partial_results
|
||||||
|
belongs_to :proposal
|
||||||
|
|
||||||
|
validates :title, presence: true
|
||||||
|
validates :author, presence: true
|
||||||
|
|
||||||
|
validates :title, length: { minimum: 4 }
|
||||||
|
validates :description, length: { maximum: Poll::Question.description_max_length }
|
||||||
|
|
||||||
|
scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) }
|
||||||
|
|
||||||
|
scope :sort_for_list, -> { order('poll_questions.proposal_id IS NULL', :created_at)}
|
||||||
|
scope :for_render, -> { includes(:author, :proposal) }
|
||||||
|
|
||||||
|
def self.search(params)
|
||||||
|
results = self.all
|
||||||
|
results = results.by_poll_id(params[:poll_id]) if params[:poll_id].present?
|
||||||
|
results = results.pg_search(params[:search]) if params[:search].present?
|
||||||
|
results
|
||||||
|
end
|
||||||
|
|
||||||
|
def searchable_values
|
||||||
|
{ title => 'A',
|
||||||
|
proposal.try(:title) => 'A',
|
||||||
|
description => 'B',
|
||||||
|
author.username => 'C',
|
||||||
|
author_visible_name => 'C' }
|
||||||
|
end
|
||||||
|
|
||||||
|
def description
|
||||||
|
super.try :html_safe
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid_answers
|
||||||
|
(super.try(:split, ',').compact || []).map(&:strip)
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy_attributes_from_proposal(proposal)
|
||||||
|
if proposal.present?
|
||||||
|
self.author = proposal.author
|
||||||
|
self.author_visible_name = proposal.author.name
|
||||||
|
self.proposal_id = proposal.id
|
||||||
|
self.title = proposal.title
|
||||||
|
self.description = proposal.description
|
||||||
|
self.valid_answers = I18n.t('poll_questions.default_valid_answers')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def answerable_by?(user)
|
||||||
|
poll.answerable_by?(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.answerable_by(user)
|
||||||
|
return none if user.nil? || user.unverified?
|
||||||
|
where(poll_id: Poll.answerable_by(user).pluck(:id))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
20
app/models/poll/recount.rb
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
class Poll
|
||||||
|
class Recount < ActiveRecord::Base
|
||||||
|
belongs_to :booth_assignment, class_name: "Poll::BoothAssignment"
|
||||||
|
belongs_to :officer_assignment, class_name: "Poll::OfficerAssignment"
|
||||||
|
|
||||||
|
validates :booth_assignment_id, presence: true
|
||||||
|
validates :date, presence: true, uniqueness: {scope: :booth_assignment_id}
|
||||||
|
validates :officer_assignment_id, presence: true, uniqueness: {scope: :booth_assignment_id}
|
||||||
|
validates :count, presence: true, numericality: {only_integer: true}
|
||||||
|
|
||||||
|
before_save :update_logs
|
||||||
|
|
||||||
|
def update_logs
|
||||||
|
if self.count_changed? && self.count_was.present?
|
||||||
|
self.count_log += ":#{self.count_was.to_s}"
|
||||||
|
self.officer_assignment_id_log += ":#{self.officer_assignment_id_was.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
59
app/models/poll/voter.rb
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
class Poll
|
||||||
|
class Voter < ActiveRecord::Base
|
||||||
|
belongs_to :poll
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :geozone
|
||||||
|
belongs_to :booth_assignment
|
||||||
|
belongs_to :officer_assignment
|
||||||
|
|
||||||
|
validates :poll_id, presence: true
|
||||||
|
validates :user_id, presence: true
|
||||||
|
|
||||||
|
validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type], message: :has_voted }
|
||||||
|
|
||||||
|
before_validation :set_demographic_info, :set_document_info
|
||||||
|
|
||||||
|
def set_demographic_info
|
||||||
|
return unless user.present?
|
||||||
|
|
||||||
|
self.gender = user.gender
|
||||||
|
self.age = user.age
|
||||||
|
self.geozone = user.geozone
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_document_info
|
||||||
|
return unless user.present?
|
||||||
|
|
||||||
|
self.document_type = user.document_type
|
||||||
|
self.document_number = user.document_number
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def in_census?
|
||||||
|
census_api_response.valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
def census_api_response
|
||||||
|
@census_api_response ||= CensusApi.new.call(document_type, document_number)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fill_stats_fields
|
||||||
|
if in_census?
|
||||||
|
self.gender = census_api_response.gender
|
||||||
|
self.geozone_id = Geozone.select(:id).where(census_code: census_api_response.district_code).first.try(:id)
|
||||||
|
self.age = voter_age(census_api_response.date_of_birth)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def voter_age(dob)
|
||||||
|
if dob.blank?
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
now = Time.now.utc.to_date
|
||||||
|
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
23
app/models/poll/white_result.rb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
class Poll::WhiteResult < ActiveRecord::Base
|
||||||
|
|
||||||
|
VALID_ORIGINS = %w{ web booth }
|
||||||
|
|
||||||
|
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||||
|
belongs_to :booth_assignment
|
||||||
|
belongs_to :officer_assignment
|
||||||
|
|
||||||
|
validates :author, presence: true
|
||||||
|
validates :origin, inclusion: {in: VALID_ORIGINS}
|
||||||
|
|
||||||
|
scope :by_author, -> (author_id) { where(author_id: author_id) }
|
||||||
|
|
||||||
|
before_save :update_logs
|
||||||
|
|
||||||
|
def update_logs
|
||||||
|
if self.amount_changed? && self.amount_was.present?
|
||||||
|
self.amount_log += ":#{self.amount_was.to_s}"
|
||||||
|
self.officer_assignment_id_log += ":#{self.officer_assignment_id_was.to_s}"
|
||||||
|
self.author_id_log += ":#{self.author_id_was.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -45,12 +45,12 @@ class Proposal < ActiveRecord::Base
|
|||||||
scope :sort_by_relevance, -> { all }
|
scope :sort_by_relevance, -> { all }
|
||||||
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||||
scope :sort_by_archival_date, -> { archived.sort_by_confidence_score }
|
scope :sort_by_archival_date, -> { archived.sort_by_confidence_score }
|
||||||
scope :archived, -> { where("proposals.created_at <= ?", Setting["months_to_archive_proposals"].to_i.months.ago)}
|
scope :archived, -> { where("proposals.created_at <= ?", Setting["months_to_archive_proposals"].to_i.months.ago) }
|
||||||
scope :not_archived, -> { where("proposals.created_at > ?", Setting["months_to_archive_proposals"].to_i.months.ago)}
|
scope :not_archived, -> { where("proposals.created_at > ?", Setting["months_to_archive_proposals"].to_i.months.ago) }
|
||||||
scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)}
|
scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)}
|
||||||
scope :retired, -> { where.not(retired_at: nil) }
|
scope :retired, -> { where.not(retired_at: nil) }
|
||||||
scope :not_retired, -> { where(retired_at: nil) }
|
scope :not_retired, -> { where(retired_at: nil) }
|
||||||
scope :successfull, -> { where("cached_votes_up >= ?", Proposal.votes_needed_for_success)}
|
scope :successful, -> { where("cached_votes_up >= ?", Proposal.votes_needed_for_success) }
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
"#{id}-#{title}".parameterize
|
"#{id}-#{title}".parameterize
|
||||||
@@ -155,7 +155,7 @@ class Proposal < ActiveRecord::Base
|
|||||||
Setting['votes_for_proposal_success'].to_i
|
Setting['votes_for_proposal_success'].to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
def successfull?
|
def successful?
|
||||||
total_votes >= Proposal.votes_needed_for_success
|
total_votes >= Proposal.votes_needed_for_success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -12,35 +12,30 @@ class Signature < ActiveRecord::Base
|
|||||||
|
|
||||||
before_validation :clean_document_number
|
before_validation :clean_document_number
|
||||||
|
|
||||||
def verified?
|
|
||||||
user_exists? || in_census?
|
|
||||||
end
|
|
||||||
|
|
||||||
def verify
|
def verify
|
||||||
if verified?
|
|
||||||
assign_vote
|
|
||||||
mark_as_verified
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def assign_vote
|
|
||||||
if user_exists?
|
if user_exists?
|
||||||
assign_vote_to_user
|
assign_vote_to_user
|
||||||
else
|
mark_as_verified
|
||||||
|
elsif in_census?
|
||||||
create_user
|
create_user
|
||||||
assign_vote_to_user
|
assign_vote_to_user
|
||||||
|
mark_as_verified
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_vote_to_user
|
def assign_vote_to_user
|
||||||
set_user
|
set_user
|
||||||
signable.register_vote(user, "yes")
|
if signable.is_a? Budget::Investment
|
||||||
|
signable.vote_by(voter: user, vote: 'yes') if [nil, :no_selecting_allowed].include?(signable.reason_for_not_being_selectable_by(user))
|
||||||
|
else
|
||||||
|
signable.register_vote(user, "yes")
|
||||||
|
end
|
||||||
assign_signature_to_vote
|
assign_signature_to_vote
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_signature_to_vote
|
def assign_signature_to_vote
|
||||||
vote = Vote.where(votable: signable, voter: user).first
|
vote = Vote.where(votable: signable, voter: user).first
|
||||||
vote.update(signature: self)
|
vote.update(signature: self) if vote
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_exists?
|
def user_exists?
|
||||||
@@ -51,11 +46,14 @@ class Signature < ActiveRecord::Base
|
|||||||
user_params = {
|
user_params = {
|
||||||
document_number: document_number,
|
document_number: document_number,
|
||||||
created_from_signature: true,
|
created_from_signature: true,
|
||||||
verified_at: Time.now,
|
verified_at: Time.current,
|
||||||
erased_at: Time.now,
|
erased_at: Time.current,
|
||||||
password: random_password,
|
password: random_password,
|
||||||
terms_of_service: '1',
|
terms_of_service: '1',
|
||||||
email: nil
|
email: nil,
|
||||||
|
date_of_birth: @census_api_response.date_of_birth,
|
||||||
|
gender: @census_api_response.gender,
|
||||||
|
geozone: Geozone.where(census_code: @census_api_response.district_code).first
|
||||||
}
|
}
|
||||||
User.create!(user_params)
|
User.create!(user_params)
|
||||||
end
|
end
|
||||||
@@ -70,10 +68,17 @@ class Signature < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def in_census?
|
def in_census?
|
||||||
response = document_types.detect do |document_type|
|
document_types.detect do |document_type|
|
||||||
CensusApi.new.call(document_type, document_number).valid?
|
response = CensusApi.new.call(document_type, document_number)
|
||||||
|
if response.valid?
|
||||||
|
@census_api_response = response
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
response.present?
|
|
||||||
|
@census_api_response.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_user
|
def set_user
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class SignatureSheet < ActiveRecord::Base
|
|||||||
belongs_to :signable, polymorphic: true
|
belongs_to :signable, polymorphic: true
|
||||||
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
|
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
|
||||||
|
|
||||||
VALID_SIGNABLES = %w( Proposal SpendingProposal )
|
VALID_SIGNABLES = %w( Proposal Budget::Investment SpendingProposal )
|
||||||
|
|
||||||
has_many :signatures
|
has_many :signatures
|
||||||
|
|
||||||
|
|||||||
5
app/models/site_customization.rb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module SiteCustomization
|
||||||
|
def self.table_name_prefix
|
||||||
|
'site_customization_'
|
||||||
|
end
|
||||||
|
end
|
||||||
11
app/models/site_customization/content_block.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
class SiteCustomization::ContentBlock < ActiveRecord::Base
|
||||||
|
VALID_BLOCKS = %w(top_links footer)
|
||||||
|
|
||||||
|
validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) }
|
||||||
|
validates :name, presence: true, uniqueness: { scope: :locale }, inclusion: { in: VALID_BLOCKS }
|
||||||
|
|
||||||
|
def self.block_for(name, locale)
|
||||||
|
locale ||= I18n.default_locale
|
||||||
|
find_by(name: name, locale: locale).try(:body)
|
||||||
|
end
|
||||||
|
end
|
||||||
48
app/models/site_customization/image.rb
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
class SiteCustomization::Image < ActiveRecord::Base
|
||||||
|
VALID_IMAGES = {
|
||||||
|
"icon_home" => [330, 240],
|
||||||
|
"logo_header" => [80, 80],
|
||||||
|
"social-media-icon" => [200, 200],
|
||||||
|
"apple-touch-icon-200" => [200, 200]
|
||||||
|
}
|
||||||
|
|
||||||
|
has_attached_file :image
|
||||||
|
|
||||||
|
validates :name, presence: true, uniqueness: true, inclusion: { in: VALID_IMAGES.keys }
|
||||||
|
validates_attachment_content_type :image, :content_type => ["image/png"]
|
||||||
|
validate :check_image
|
||||||
|
|
||||||
|
def self.all_images
|
||||||
|
VALID_IMAGES.keys.map do |image_name|
|
||||||
|
find_by(name: image_name) || create!(name: image_name.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.image_path_for(filename)
|
||||||
|
image_name = filename.split(".").first
|
||||||
|
|
||||||
|
if i = find_by(name: image_name)
|
||||||
|
i.image.exists? ? i.image.url : nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def required_width
|
||||||
|
VALID_IMAGES[name].try(:first)
|
||||||
|
end
|
||||||
|
|
||||||
|
def required_height
|
||||||
|
VALID_IMAGES[name].try(:second)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_image
|
||||||
|
return unless image?
|
||||||
|
|
||||||
|
dimensions = Paperclip::Geometry.from_file(image.queued_for_write[:original].path)
|
||||||
|
|
||||||
|
errors.add(:image, :image_width, required_width: required_width) unless dimensions.width == required_width
|
||||||
|
errors.add(:image, :image_height, required_height: required_height) unless dimensions.height == required_height
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
16
app/models/site_customization/page.rb
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
class SiteCustomization::Page < ActiveRecord::Base
|
||||||
|
VALID_STATUSES = %w(draft published)
|
||||||
|
|
||||||
|
validates :slug, presence: true,
|
||||||
|
uniqueness: { case_sensitive: false },
|
||||||
|
format: { with: /\A[0-9a-zA-Z\-_]*\Z/, message: :slug_format }
|
||||||
|
validates :title, presence: true
|
||||||
|
validates :status, presence: true, inclusion: { in: VALID_STATUSES }
|
||||||
|
|
||||||
|
scope :published, -> { where(status: 'published').order('id DESC') }
|
||||||
|
scope :with_more_info_flag, -> { where(status: 'published', more_info_flag: true).order('id ASC') }
|
||||||
|
|
||||||
|
def url
|
||||||
|
"/#{slug}"
|
||||||
|
end
|
||||||
|
end
|
||||||