diff --git a/Gemfile b/Gemfile
index 339f0707..fd188057 100644
--- a/Gemfile
+++ b/Gemfile
@@ -12,7 +12,9 @@ gem 'sidekiq', '~> 2.13.0'
gem 'sinatra', require: false # required by sidekiq web interface mounted on /sidekiq
# Turns every field on a editable one
-gem 'best_in_place', github: 'bernat/best_in_place', branch: 'rails-4'
+gem 'best_in_place', github: 'widernet/best_in_place', branch: 'rails-4'
+#gem 'best_in_place', github: 'bernat/best_in_place', ref: '769ba1887feafb2b46693fe52c2953230d61c5e1'
+#gem 'best_in_place', '2.1.3'
# State machine for attributes on models
gem 'state_machine', require: 'state_machine/core'
@@ -22,15 +24,16 @@ gem 'paper_trail', github: 'airblade/paper_trail', branch: 'rails4'
# Database and data related
gem 'pg'
-gem 'postgres-copy', github: 'josemarluedke/postgres-copy', branch: 'rails4'
+gem 'postgres-copy'#, github: 'josemarluedke/postgres-copy', branch: 'rails4'
gem 'pg_search'
gem 'schema_plus', '~> 1.2.0'
gem 'schema_associations', '~> 1.2.0'
gem 'chartkick'
# Payment engines
-gem 'catarse_paypal_express', '~> 2.0.0'
-gem 'catarse_moip', '~> 2.0.0'
+#gem 'catarse_paypal_express', '~> 2.0.0'
+#gem 'catarse_moip', '~> 2.0.0'
+gem 'catarse_pagarme', github: 'engageis/catarse_pagarme', branch: 'v1'
#
# Decorators
gem 'draper'
@@ -55,6 +58,7 @@ gem 'catarse_mailchimp', git: 'git://github.com/catarse/catarse_mailchimp', ref:
# HTML manipulation and formatting
gem 'formtastic', '~> 2.2.1'
+gem 'simple_form'
gem "auto_html", '= 1.4.2'
gem 'kaminari'
@@ -135,6 +139,7 @@ end
gem 'sass-rails', '~> 4.0.0'
gem 'coffee-rails', '~> 4.0.0'
gem "compass-rails", '~> 1.1.0'
+gem 'sprockets', '2.10.0'
gem 'uglifier'
gem 'compass-960-plugin'
diff --git a/Gemfile.lock b/Gemfile.lock
index 458815d5..3faed772 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -7,15 +7,6 @@ GIT
activerecord (~> 4.0)
railties (~> 4.0)
-GIT
- remote: git://github.com/bernat/best_in_place.git
- revision: 366413be357d65cdf47031e928aea969f72e3659
- branch: rails-4
- specs:
- best_in_place (2.0.3)
- jquery-rails
- rails (~> 4)
-
GIT
remote: git://github.com/catarse/catarse_mailchimp
revision: 2ed4f3931dfa292e5c1c62619772f04e41c68629
@@ -35,15 +26,13 @@ GIT
nokogiri (~> 1.5.0)
GIT
- remote: git://github.com/josemarluedke/postgres-copy.git
- revision: 41afec70f5c6b2431f045388b14a80d194329a20
- branch: rails4
+ remote: git://github.com/engageis/catarse_pagarme.git
+ revision: ff69884bbcca44795091af8b7d51218a2a66da97
+ branch: v1
specs:
- postgres-copy (0.6.0)
- activerecord (>= 3.0.0)
- pg
- rails (>= 3.0.0)
- responders
+ catarse_pagarme (1.4.8)
+ pagarme (~> 1.9.8)
+ rails (~> 4.0)
GIT
remote: git://github.com/ryanb/cancan.git
@@ -53,6 +42,15 @@ GIT
specs:
cancan (2.0.0.alpha)
+GIT
+ remote: git://github.com/widernet/best_in_place.git
+ revision: 964f3f36fe24cd7cd304b44f4ffac2ee1de3cd1e
+ branch: rails-4
+ specs:
+ best_in_place (2.0.3)
+ jquery-rails
+ rails (~> 4)
+
GEM
remote: https://rubygems.org/
specs:
@@ -66,17 +64,6 @@ GEM
erubis (~> 2.7.0)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
- active_utils (2.0.0)
- activesupport (>= 2.3.11)
- i18n
- activemerchant (1.36.0)
- active_utils (>= 1.0.2)
- activesupport (>= 2.3.14)
- builder (>= 2.0.0)
- i18n
- json (>= 1.5.1)
- money
- nokogiri (< 1.6.0)
activemodel (4.0.0)
activesupport (= 4.0.0)
builder (~> 3.1.0)
@@ -93,8 +80,7 @@ GEM
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
addressable (2.3.5)
- arel (4.0.0)
- atomic (1.1.13)
+ arel (4.0.2)
auto_html (1.4.2)
RedCloth
redcarpet
@@ -116,13 +102,6 @@ GEM
carrierwave (0.8.0)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
- catarse_moip (2.0.0)
- libxml-ruby (~> 2.6.0)
- rails (~> 4.0)
- catarse_paypal_express (2.0.0)
- activemerchant (>= 1.34.0)
- rails (~> 4.0)
- slim-rails
celluloid (0.14.1)
timers (>= 1.0.0)
chartkick (1.2.0)
@@ -224,7 +203,7 @@ GEM
crack (= 0.1.8)
httpauth (0.2.0)
httpclient (2.3.4.1)
- i18n (0.6.5)
+ i18n (0.6.11)
inherited_resources (1.4.1)
has_scope (~> 0.6.0.rc)
responders (~> 1.0.0.rc)
@@ -248,7 +227,6 @@ GEM
addressable (~> 2.3)
letter_opener (1.1.2)
launchy (~> 2.2)
- libxml-ruby (2.6.0)
loofah (1.2.1)
nokogiri (>= 1.4.4)
mail (2.5.3)
@@ -258,15 +236,14 @@ GEM
mailchimp (0.0.9)
httparty
method_source (0.8.2)
- mime-types (1.24)
+ mime-types (1.25.1)
minitest (4.7.5)
- money (5.1.1)
- i18n (~> 0.6.0)
- multi_json (1.7.9)
+ multi_json (1.10.1)
multipart-post (1.2.0)
net-scp (1.1.2)
net-ssh (>= 2.6.5)
net-ssh (2.6.8)
+ netrc (0.10.2)
newrelic_rpm (3.6.6.147)
nokogiri (1.5.10)
oauth (0.4.7)
@@ -291,6 +268,9 @@ GEM
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
orm_adapter (0.4.0)
+ pagarme (1.9.8)
+ multi_json
+ rest-client
pg (0.17.0)
pg_search (0.7.0)
activerecord (>= 3.1)
@@ -300,7 +280,12 @@ GEM
capybara (~> 2.1.0)
faye-websocket (>= 0.4.4, < 0.5.0)
http_parser.rb (~> 0.5.3)
- polyglot (0.3.3)
+ polyglot (0.3.5)
+ postgres-copy (0.9.0)
+ activerecord (>= 4.0)
+ pg (>= 0.17)
+ rails (>= 4.0)
+ responders
protected_attributes (1.0.3)
activemodel (>= 4.0.0, < 5.0)
pry (0.9.12.2)
@@ -336,7 +321,7 @@ GEM
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
raindrops (0.11.0)
- rake (10.1.0)
+ rake (10.4.2)
ranked-model (0.3)
activerecord (>= 3.1.12)
redcarpet (3.0.0)
@@ -346,8 +331,9 @@ GEM
request_store (1.0.5)
responders (1.0.0.rc)
railties (>= 3.2, < 5)
- rest-client (1.6.7)
- mime-types (>= 1.16)
+ rest-client (1.7.2)
+ mime-types (>= 1.16, < 3.0)
+ netrc (~> 0.7)
rinku (1.7.3)
rmagick (2.13.2)
routing-filter (0.4.0.pre)
@@ -398,6 +384,9 @@ GEM
json
redis (>= 3.0)
redis-namespace
+ simple_form (3.0.0)
+ actionpack (>= 4.0.0, < 4.1)
+ activemodel (>= 4.0.0, < 4.1)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
@@ -431,15 +420,176 @@ GEM
activemodel (>= 3.0.0.beta)
tag_helper (0.0.3)
temple (0.6.6)
- thor (0.18.1)
- thread_safe (0.1.2)
- atomic
+ thor (0.19.1)
+ thread_safe (0.3.4)
tilt (1.4.1)
timers (1.1.0)
- treetop (1.4.14)
+ treetop (1.4.15)
+ polyglot
polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
+ polyglot (>= 0.3.1)
polyglot (>= 0.3.1)
- tzinfo (0.3.37)
+ tzinfo (0.3.42)
uglifier (2.1.2)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
@@ -471,8 +621,7 @@ DEPENDENCIES
capybara (~> 2.1.0)
carrierwave (~> 0.8.0)
catarse_mailchimp!
- catarse_moip (~> 2.0.0)
- catarse_paypal_express (~> 2.0.0)
+ catarse_pagarme!
chartkick
coffee-rails (~> 4.0.0)
compass-960-plugin
@@ -510,7 +659,7 @@ DEPENDENCIES
pg
pg_search
poltergeist
- postgres-copy!
+ postgres-copy
protected_attributes (~> 1.0.3)
pry
rack-timeout
@@ -528,9 +677,11 @@ DEPENDENCIES
selenium-webdriver (~> 2.34.0)
shoulda
sidekiq (~> 2.13.0)
+ simple_form
sinatra
slim-rails (~> 1.1.1)
spectator-validates_email
+ sprockets (= 2.10.0)
state_machine
uglifier
unicorn
diff --git a/app/assets/javascripts/app/user.js b/app/assets/javascripts/app/user.js
index 815a4220..e185210a 100644
--- a/app/assets/javascripts/app/user.js
+++ b/app/assets/javascripts/app/user.js
@@ -12,6 +12,7 @@ App.addChild('User', _.extend({
this.makeRoute('credits');
this.makeRoute('settings');
this.makeRoute('unsubscribes');
+ this.makeRoute('credit_cards');
},
makeRoute: function(name){
diff --git a/app/assets/javascripts/lib/jquery.brbanks.js b/app/assets/javascripts/lib/jquery.brbanks.js
new file mode 100644
index 00000000..45bfcc8f
--- /dev/null
+++ b/app/assets/javascripts/lib/jquery.brbanks.js
@@ -0,0 +1,103 @@
+(function($){
+ $.fn.extend({
+ brbanks: function(options) {
+ var root = this;
+
+ local = {
+ selector: this,
+ bankDivSelector: '.brbanks-banks',
+ banks: [],
+
+ parseToList: function(banks_data) {
+ that = this;
+ $.each(banks_data, function(i,item){
+ that.banks.push(item.id + ' - ' + item.name)
+ });
+
+ that.inserListOnData();
+ },
+
+ inserListOnData: function() {
+ this.selector.data('banks', this.banks);
+ },
+
+ loadBanksOnSelector: function(callback) {
+ var that = this;
+ $.getJSON("http://brbanks.herokuapp.com", function(data){
+ that.parseToList(data);
+ callback(that);
+ });
+ },
+
+ buildBankDiv: function() {
+ var div = $("
")
+ var ul = $("")
+
+ $.each(this.selector.data('banks'), function(i, item){
+ ul.append($(''+item+''));
+ });
+
+ div.prepend(ul);
+ return div;
+ }
+ }
+
+ showUpBanks = function(that) {
+ that.selector.focusin(function(){
+ if($(that.bankDivSelector).length <= 0) {
+ var div = that.buildBankDiv();
+ that.selector.parent().append(div);
+ div.show();
+ } else {
+ $(that.bankDivSelector).show();
+ };
+
+ $('ul li', that.bankDivSelector).click(function(element){
+ root.val($(element.currentTarget).text());
+ $(that.bankDivSelector).hide();
+ })
+ });
+
+ $(document).mouseup(function(e){
+ if(!$(that.bankDivSelector).is(e.target) && !that.selector.is(e.target)) {
+ $(that.bankDivSelector).hide();
+ $('ul li', that.bankDivSelector).css({display: 'block'});
+
+ if($.inArray($(that.selector).val(), that.banks) < 0) {
+ $(that.selector).val('');
+ };
+ }
+ });
+ };
+
+ enableFilterOnBanks = function(that) {
+ that.selector.keyup(function(){
+ var value = that.selector.val();
+ var regexPattern = new RegExp(value, 'i');
+
+ $('ul li', that.bankDivSelector).filter(function(){
+ if(regexPattern.test($(this).text())) {
+ $(this).fadeIn();
+ } else {
+ $(this).css({'display':'none'});
+ $(this).fadeOut();
+ }
+ });
+ //$.each($('ul li', that.bankDivSelector), function(i, item){
+ // if(regexPattern.test($(item).text())){
+ // $(item).css({'display':'block'})
+ // } else {
+ // $(item).css({'display':'none'})
+ // }
+ //});
+ });
+ };
+
+ local.loadBanksOnSelector(function(that) {
+ showUpBanks(that);
+ enableFilterOnBanks(that);
+ });
+ }
+ });
+})(jQuery);
+
diff --git a/app/assets/stylesheets/miv/_index.sass b/app/assets/stylesheets/miv/_index.sass
index 6cb8872d..8ef65baf 100644
--- a/app/assets/stylesheets/miv/_index.sass
+++ b/app/assets/stylesheets/miv/_index.sass
@@ -34,7 +34,7 @@
+box-shadow(rgba(black,0.75) 0px 0px 5px inset !important)
&:active
+box-shadow(rgba(black, 1) 0px 0px 15px inset !important)
-
+
#announcement
display: block
padding: 10px
@@ -148,4 +148,50 @@ span.on_the_spot_editing
.avatar_wrapper
overflow: hidden
-
+.brbanks-banks
+ margin: 0 !important
+ padding: 5px !important
+ position: absolute
+ width: 260px
+ max-height: 200px
+ overflow: auto
+ background: white
+ border: #dfdfdf 1px solid
+ border-radius: 4px
+ ul
+ padding: 0 !important
+ margin: 0 !important
+ list-style-position: inside
+ list-style-type: none
+ li
+ margin: 0 !important
+ font-size: 12px !important
+ padding: 5px 0
+ &:hover
+ background: #ededed
+.bank_accounts
+ .input, .inputs
+ float: left
+ width: 160px
+ #user_bank_account_attributes_agency_input, .user_bank_account_agency
+ width: 60px
+ input[type='text']
+ width: 40px
+ #user_bank_account_attributes_agency_digit_input, .user_bank_account_agency_digit
+ width: 60px
+ input[type='text']
+ width: 40px
+ #user_bank_account_attributes_name_input, .user_bank_account_name
+ width: 220px
+ input[type='text']
+ width: 200px
+ #user_bank_account_attributes_account_input, .user_bank_account_account
+ width: 150px
+ input[type='text']
+ width: 130px
+ #user_bank_account_attributes_account_digit_input, .user_bank_account_account_digit
+ width: 60px
+ input[type='text']
+ width: 40px
+ input[type='text']
+ width: 140px
diff --git a/app/assets/stylesheets/resources/backers/_create.sass b/app/assets/stylesheets/resources/backers/_create.sass
index 931c080a..8155844f 100644
--- a/app/assets/stylesheets/resources/backers/_create.sass
+++ b/app/assets/stylesheets/resources/backers/_create.sass
@@ -430,3 +430,34 @@
text-decoration: none
&:hover
text-decoration: underline
+ .save_card
+ input[type='checkbox']
+ float: left
+ margin-right: 10px
+ label
+ float: left
+ ul.my_credit_cards
+ list-style-position: none
+ list-style-type: none
+ width: 100%
+ li
+ width: 90%
+ display: block
+ padding: 10px 10px 5px
+ border: 1px solid #DFDFDF
+ background: #F4F4F4
+ .radio_button
+ float: left
+ width: 5%
+ .select_installments
+ float: left
+ width: 30%
+ select
+ width: 90%
+ .card_info
+ float: left
+ width: 40%
+ margin-left: 10px
+ .card_brand
+ float: left
+ width: 10%
diff --git a/app/controllers/users/credit_cards_controller.rb b/app/controllers/users/credit_cards_controller.rb
new file mode 100644
index 00000000..c8bffd2a
--- /dev/null
+++ b/app/controllers/users/credit_cards_controller.rb
@@ -0,0 +1,11 @@
+class Users::CreditCardsController < ApplicationController
+ load_and_authorize_resource
+ inherit_resources
+ actions :destroy
+ belongs_to :user
+
+ def destroy
+ resource.cancel_subscription
+ destroy! { user_path(parent, anchor: 'credit_cards') }
+ end
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index e9289049..945112c3 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -20,6 +20,8 @@ def show
@credits = @user.backs.can_refund
@subscribed_to_updates = @user.updates_subscription
@unsubscribes = @user.project_unsubscribes
+ @credit_cards = @user.credit_cards
+ build_bank_account
}
end
@@ -74,4 +76,9 @@ def credits
@credits = @user.backs.can_refund.order(:id).all
render json: @credits
end
+
+ private
+ def build_bank_account
+ @user.build_bank_account unless @user.bank_account
+ end
end
diff --git a/app/decorators/credit_card_decorator.rb b/app/decorators/credit_card_decorator.rb
new file mode 100644
index 00000000..527c9c4b
--- /dev/null
+++ b/app/decorators/credit_card_decorator.rb
@@ -0,0 +1,8 @@
+class CreditCardDecorator < Draper::Decorator
+ decorates :credit_card
+ include Draper::LazyHelpers
+
+ def display_digits
+ "XXXX-XXXX-XXXX-#{source.last_digits}"
+ end
+end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 302427d1..51aee2ee 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -26,6 +26,11 @@ def initialize(current_user, options = {})
project.user == current_user && ( project.draft? || project.rejected? )
end
+ # NOTE: Credit card authorizations
+ can :access, :credit_cards do |credit_card|
+ credit_card.user == current_user
+ end
+
# NOTE: Reward authorizations
can :create, :rewards do |reward|
diff --git a/app/models/bank.rb b/app/models/bank.rb
new file mode 100644
index 00000000..de36a007
--- /dev/null
+++ b/app/models/bank.rb
@@ -0,0 +1,20 @@
+class Bank < ActiveRecord::Base
+ has_many :bank_accounts
+
+ validates :name, :code, presence: true
+ scope :order_popular, ->{
+ select('banks.code, banks.id, banks.name, count(bank_accounts.bank_id) as total').
+ joins('left join bank_accounts on bank_accounts.bank_id = banks.id').
+ group('banks.id, bank_accounts.bank_id').order('total DESC')
+ }
+
+ def self.to_collection
+ order_popular.map do |bank|
+ [bank.to_s, bank.id]
+ end
+ end
+
+ def to_s
+ [code, name].join(' . ')
+ end
+end
diff --git a/app/models/bank_account.rb b/app/models/bank_account.rb
new file mode 100644
index 00000000..34a0d0ff
--- /dev/null
+++ b/app/models/bank_account.rb
@@ -0,0 +1,13 @@
+class BankAccount < ActiveRecord::Base
+ #include CatarsePagarme::BankAccountConcern
+
+ belongs_to :user
+ belongs_to :bank
+
+ validates :bank_id, :agency, :account, :owner_name, :owner_document, :account_digit, presence: true
+
+ def bank_code
+ self.bank.code
+ end
+end
+
diff --git a/app/models/credit_card.rb b/app/models/credit_card.rb
new file mode 100644
index 00000000..8459eec4
--- /dev/null
+++ b/app/models/credit_card.rb
@@ -0,0 +1,17 @@
+class CreditCard < ActiveRecord::Base
+ belongs_to :user
+
+ validates :user, :last_digits, :card_brand, :subscription_id, presence: true
+ delegate :display_digits, to: :decorator
+
+ def decorator
+ CreditCardDecorator.new(self)
+ end
+
+ def cancel_subscription
+ if defined?(CatarsePagarme)
+ self.pagarme_delegator.cancel_subscription
+ end
+ end
+end
+
diff --git a/app/models/user.rb b/app/models/user.rb
index 589c3bd7..1ae54be4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -52,7 +52,8 @@ class User < ActiveRecord::Base
:twitter,
:facebook_link,
:other_link,
- :moip_login
+ :moip_login,
+ :bank_account_attributes
mount_uploader :uploaded_image, UserUploader
@@ -69,7 +70,9 @@ class User < ActiveRecord::Base
schema_associations
has_many :oauth_providers, through: :authorizations
has_many :backs, class_name: "Backer"
+ has_many :credit_cards
has_one :user_total
+ has_one :bank_account
has_and_belongs_to_many :recommended_projects, join_table: :recommendations, class_name: 'Project'
@@ -80,6 +83,7 @@ class User < ActiveRecord::Base
has_many :channels_subscribers
accepts_nested_attributes_for :unsubscribes, allow_destroy: true rescue puts "No association found for name 'unsubscribes'. Has it been defined yet?"
+ accepts_nested_attributes_for :bank_account, allow_destroy: true
scope :backers, -> {
where("id IN (
diff --git a/app/views/projects/backers/create.html.slim b/app/views/projects/backers/create.html.slim
index 2f9a973a..182e9c69 100644
--- a/app/views/projects/backers/create.html.slim
+++ b/app/views/projects/backers/create.html.slim
@@ -1,6 +1,8 @@
#page_content
.container
#project_review data-thank-you-path=project_backer_path(project_id: @project.id, id: @backer.id)
+ = hidden_field_tag :contribution_id, @backer.id
+ = hidden_field_tag :project_id, @project.id
.project_info
= image_tag @project.display_image, id: 'project_image', alt: @project.name, width: '250px'
h1= t('.you_are_about_html', link: link_to(@project.name, project_by_slug_path(permalink: @project.permalink)))
@@ -65,10 +67,10 @@
.tab_container
nav#payment_menu
- PaymentEngines.engines.each do |engine|
- - unless engine[:name] == 'moip'
- = link_to "##{engine[:name]}_payment", id: engine[:name], class: 'selected enabled' , data: {target: "##{engine[:name]}_payment"} do
- = t("projects.backers.review.#{engine[:name]}")
+ - unless engine.name == 'moip'
+ = link_to "##{engine.name}_payment", id: engine.name, class: 'selected enabled' , data: {target: "##{engine.name}_payment"} do
+ = t("projects.backers.review.#{engine.name}")
.tab_content_container
- PaymentEngines.engines.each do |engine|
- div[id="#{engine[:name]}_payment" class="payments_type hide" data-path=engine[:review_path].call(@backer) ]
+ div[id="#{engine.name}_payment" class="payments_type hide" data-path=engine.review_path(@backer) ]
.clearfix
diff --git a/app/views/users/_credit_cards.html.slim b/app/views/users/_credit_cards.html.slim
new file mode 100644
index 00000000..e248e616
--- /dev/null
+++ b/app/views/users/_credit_cards.html.slim
@@ -0,0 +1,13 @@
+.table_content
+ table.table.table-striped
+ thead
+ th= t('.index.last_digits')
+ th= t('.index.brand')
+ th
+ - @credit_cards.each do |card|
+ tr
+ td.card_name= card.display_digits
+ td.brand= card.card_brand
+ td.actions
+ .bootstrap-twitter
+ = link_to t('.index.remove'), user_credit_card_path(@user, card), class: 'btn btn-danger', method: :delete, data: { confirm: 'você tem certeza?' }
diff --git a/app/views/users/_current_user_fields.html.slim b/app/views/users/_current_user_fields.html.slim
index bee3ca3b..d709312e 100644
--- a/app/views/users/_current_user_fields.html.slim
+++ b/app/views/users/_current_user_fields.html.slim
@@ -1,3 +1,25 @@
+#bank_account.user_data
+ h1= t('.bank_account_title')
+ br/
+ ul
+ li
+ .bootstrap-form
+ = semantic_form_for @user, html: {method: :put, id: 'user_form'} do |f|
+ .bank_accounts
+ = f.semantic_fields_for :bank_account do |bank_form|
+ = bank_form.input :bank_id, as: :select, collection: Bank.to_collection
+ .clearfix
+ = bank_form.input :agency, as: :string
+ = bank_form.input :agency_digit, as: :string
+ .clearfix
+ = bank_form.input :account, as: :string
+ = bank_form.input :account_digit, as: :string
+ .clearfix
+ = bank_form.input :owner_name, as: :string, input_html: { value: bank_form.object.owner_name || @user.full_name }
+ = bank_form.input :owner_document, as: :string, input_html: { value: bank_form.object.owner_document || @user.cpf }
+ .clearfix
+ .bootstrap-twitter
+ p= f.submit t('.update_social_info'), class: 'btn'
#my_avatar
h1 = t('.local_avatar')
ul
diff --git a/app/views/users/show.html.slim b/app/views/users/show.html.slim
index 5873108c..95d067ea 100644
--- a/app/views/users/show.html.slim
+++ b/app/views/users/show.html.slim
@@ -41,6 +41,8 @@
= link_to t('.tabs.credits'), '#credits', id: 'credits_link', data: { target: '#user_credits' }
= link_to t('.tabs.settings'), '#settings', id: 'settings_link', data: { target: '#user_settings' }
= link_to t('.tabs.unsubscribes'), '#unsubscribes', id: 'unsubscribes_link', data: { target: '#user_unsubscribes' }
+ - if @credit_cards.present?
+ = link_to t('.tabs.credit_cards'), '#credit_cards', id: 'credit_cards_link', data: { target: '#user_credit_cards' }
.clearfix
#user_profile_content
#user_backed_projects.content[data-path=user_backers_path(@user)]
@@ -68,5 +70,10 @@
= render 'current_user_fields'
#user_credits.content.hide
= render 'credits'
+ - if @credit_cards.present?
+ #user_credit_cards.content.hide
+ = render 'credit_cards'
+
+
.clearfix
.clearfix
diff --git a/config/initializers/pagarme.rb b/config/initializers/pagarme.rb
new file mode 100644
index 00000000..e5f6051a
--- /dev/null
+++ b/config/initializers/pagarme.rb
@@ -0,0 +1,12 @@
+CatarsePagarme.configure do |config|
+ config.api_key = Configuration[:pagarme_api_key]
+ config.slip_tax = Configuration[:pagarme_slip_tax]
+ config.credit_card_tax = Configuration[:pagarme_credit_card_tax]
+ config.interest_rate = Configuration[:pagarme_interest_rate]
+ config.credit_card_cents_fee = Configuration[:pagarme_cents_fee]
+ config.host = Configuration[:host]
+ config.subdomain = 'www'
+ config.protocol = 'http'
+ config.max_installments = Configuration[:pagarme_max_installments]
+ config.minimum_value_for_installment = Configuration[:pagarme_minimum_value_for_installment]
+end
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index 7a3727de..2e17b7e0 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -177,11 +177,21 @@ pt:
password: Senha
password_confirmation: "Confirmação de senha"
phone_number: "Telefone (fixo ou celular)"
+ bank_account:
+ bank: 'Banco'
+ bank_id: 'Banco'
+ owner_name: 'Nome do titular'
+ owner_document: 'CPF / CNPJ do titular'
+ agency: 'Agência'
+ agency_digit: 'Dígito'
+ account: 'Número da conta'
+ account_digit: 'Dígito'
models:
backer: Apoiador
category: Categoria
project: Projeto
reward: Recompensa
+ bank_account: Dados bancários
backer:
display_confirmed_at: "Há %{time_ago}"
reward_must_be_from_project: "deve ser do mesmo projeto"
@@ -396,6 +406,60 @@ pt:
draft: "Esse projeto é apenas um rascunho e ainda não está aberto para receber apoios."
reached_of: "Atingidos de"
submit: "Apoiar este projeto"
+ contributions:
+ review:
+ Credits: 'Créditos'
+ error: Ooops. Ocorreu um erro ao registrar seu apoio. Por favor, tente novamente.
+ form:
+ labels:
+ payment_boleto: Pagamento com Boleto
+ payment_card: Pagamento com Cartão
+ submit: Efetuar pagamento
+ build_boleto: Gerar boleto
+ payment_boleto_subtitle: "Clique no link abaixo para ver o boleto:"
+ edit:
+ form_labels:
+ payment_card_number: 'Número do cartão de crédito'
+ payment_card_flag: 'Bandeira'
+ payment_card_source: 'Código de Segurança'
+ payment_card_date: 'Data de Expiração'
+ payment_card_name: 'Nome impresso no cartão de crédito'
+ payment_card_installments: 'Parcelas'
+ installment_with_tax: 'sem juros'
+ transaction_error: 'Transação recusada, por favor verifique novamente seus dados ou entre em contato com o banco/emissor do cartão para maiores informações.'
+ pagarme_warning_html: "O Catarse está em fase de teste de um novo meio de pagamento que facilitará o apoio financeiro e o eventual reembolso dos valores aos apoiadores. Dessa forma, alertamos que poderão ser exigidos dados extras, além daqueles mencionados nos Termos de Uso para apoiar este projeto. Qualquer dúvida ou dificuldade, entre em contato conosco pelo e-mail %{mailto} . Obrigado."
+ payment_save_card: 'Quero salvar meu cartão de crédito para facilitar apoios futuros.'
+ reward_sold_out: Essa recompensa está esgotada. Inicie um novo apoio.
+ credits_preview_html: "Você possui %{credits} em créditos para realizar esse apoio até o dia 10/11, conforme novas regras divulgadas pelo Catarse."
+ credits_submit: 'Efetuar pagamento'
+ credits_title: 'Pagamento com créditos'
+ insufficient_credits: "Você possui %{credits} em créditos. Esse valor não é suficiente para realizar o apoio, por favor escolha outro meio de pagamento."
+ choose_payment: Como você quer pagar?
+ choose_payment_subtitle: Selecione abaixo uma forma de pagamento
+ cpf: 'Para prosseguir, por favor informe:'
+ credits_notice_html: Este apoio será pago com seus créditos. Após a confirmação,
+ você ficará com um saldo de %{credits} em créditos para
+ apoiar outros projetos.
+ live_in_brazil: Moro no Brasil. ( Desmarque caso o seu apoio seja internacional
+ )
+ number_card: Dados do cartão
+ owner_card: Dados do titular do cartão
+ payment_account: Pagamento com Débito em Conta
+ payment_boleto: Pagamento com Boleto
+ payment_card: Pagamento com Cartão
+ review_with_reward_html: 'Você irá apoiar com %{value} e
+ ganhará a seguinte recompensa:'
+ review_without_reward_html: Você irá apoiar com %{value}
+ e não quer nenhuma recompensa por seu apoio.
+ select_account: 'Você será redirecionado para o site do seu banco:'
+ select_boleto: 'Para prosseguir, por favor selecione:'
+ submit:
+ credits: Confirmar
+ moip: Efetuar pagamento pelo MoIP
+ subtitle: Estes dados serão informados ao organizador do projeto.
+ title: Preencha e revise os dados para pagamento
+ you_are_about_html: Você está prestes a fazer parte do grupo que faz de tudo
+ para o %{link} acontecer.
backers:
backer:
anonymous_backer: "Apoiador anônimo"
@@ -813,9 +877,16 @@ pt:
site_title: 'Defina um email de contato'
title: 'Defina um email de contato'
submit: 'Gravar o email e prosseguir'
+ credit_cards:
+ index:
+ last_digits: 'Cartão'
+ brand: 'Operadora'
+ title: 'Cartões de credito'
+ remove: 'Remover'
show:
attention: "Atenção"
tabs:
+ credit_cards: "Cartões de credito"
backed_projects: "Projetos apoiados"
created_projects: "Projetos criados"
comments: Comentários
@@ -838,6 +909,8 @@ pt:
title: "Escolha de quais projetos você deseja receber notificações:"
updates: "Eu quero receber atualizações dos projetos"
current_user_fields:
+ bank_account_title: "Dados bancários"
+ bank_account_hint: "Seus dados bancários serão utilizados para realizar o reembolso integral do seu apoio, caso o projeto não atinja 100% da meta estabelecida."
my_facebook: 'Integração com o facebook'
bio_limit: 'até 140 caracteres'
updated: "As suas informações foram atualizadas"
diff --git a/config/routes.rb b/config/routes.rb
index 7f22f2fe..bf8f802c 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -24,8 +24,9 @@
mount Sidekiq::Web => '/sidekiq'
end
- mount CatarsePaypalExpress::Engine => "/", as: :catarse_paypal_express
- mount CatarseMoip::Engine => "/", as: :catarse_moip
+ #mount CatarsePaypalExpress::Engine => "/", as: :catarse_paypal_express
+ #mount CatarseMoip::Engine => "/", as: :catarse_moip
+ mount CatarsePagarme::Engine => "/", as: :catarse_pagarme
# Non production routes
if Rails.env.development?
@@ -102,6 +103,7 @@
end
resources :users do
resources :projects, controller: 'users/projects', only: [ :index ]
+ resources :credit_cards, controller: 'users/credit_cards', only: [ :destroy ]
collection do
get :uservoice_gadget
end
diff --git a/db/migrate/20141211124556_create_bank_accounts.rb b/db/migrate/20141211124556_create_bank_accounts.rb
new file mode 100644
index 00000000..58e81226
--- /dev/null
+++ b/db/migrate/20141211124556_create_bank_accounts.rb
@@ -0,0 +1,17 @@
+class CreateBankAccounts < ActiveRecord::Migration
+ def change
+ create_table :bank_accounts do |t|
+ t.references :user, index: true
+ t.text :name, null: false
+ t.text :account, null: false
+ t.text :account_digit
+ t.text :agency, null: false
+ t.text :agency_digit
+ t.text :owner_name, null: false
+ t.text :owner_document, null: false
+
+ t.timestamps
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20141211125209_create_banks.rb b/db/migrate/20141211125209_create_banks.rb
new file mode 100644
index 00000000..645c496c
--- /dev/null
+++ b/db/migrate/20141211125209_create_banks.rb
@@ -0,0 +1,11 @@
+class CreateBanks < ActiveRecord::Migration
+ def change
+ create_table :banks do |t|
+ t.text :name, null: false
+ t.text :code, null: false
+
+ t.timestamps
+ end
+ add_index :banks, :code, unique: true
+ end
+end
diff --git a/db/migrate/20141211125359_add_bank_into_bank_accounts.rb b/db/migrate/20141211125359_add_bank_into_bank_accounts.rb
new file mode 100644
index 00000000..9e0ed39a
--- /dev/null
+++ b/db/migrate/20141211125359_add_bank_into_bank_accounts.rb
@@ -0,0 +1,5 @@
+class AddBankIntoBankAccounts < ActiveRecord::Migration
+ def change
+ add_column :bank_accounts, :bank_id, :integer, index: true
+ end
+end
diff --git a/db/migrate/20141211130230_change_remove_name_from_bank_accounts.rb b/db/migrate/20141211130230_change_remove_name_from_bank_accounts.rb
new file mode 100644
index 00000000..3658991f
--- /dev/null
+++ b/db/migrate/20141211130230_change_remove_name_from_bank_accounts.rb
@@ -0,0 +1,5 @@
+class ChangeRemoveNameFromBankAccounts < ActiveRecord::Migration
+ def change
+ remove_column :bank_accounts, :name
+ end
+end
diff --git a/db/migrate/20141211134156_insert_banks.rb b/db/migrate/20141211134156_insert_banks.rb
new file mode 100644
index 00000000..e7c244d0
--- /dev/null
+++ b/db/migrate/20141211134156_insert_banks.rb
@@ -0,0 +1,148 @@
+class InsertBanks < ActiveRecord::Migration
+ def up
+ execute <