cirandas.net

commit 0a510b929bc5205032d4257a292fef8dc8d3e5bf

Author: Hugo Melo <hugo@riseup.net>

Merge branch 'master' of github.com:coletivoEITA/noosfero-ecosol

 Gemfile.lock | 197 
 app/controllers/application_controller.rb | 2 
 app/mailers/mail_queuer.rb | 116 
 app/models/mail_schedule.rb | 3 
 config/Gemfile | 3 
 config/application.rb | 5 
 config/initializers/mail_queuer.rb | 5 
 db/migrate/20170701160657_add_mail_schedules.rb | 9 
 db/schema.rb | 1156 
 plugins/orders_cycle/models/orders_cycle_plugin/sale.rb | 1 
 plugins/products/views/products_plugin/page/show.html.erb | 2 
 plugins/suppliers/public/javascripts/views/consumer-box.tag.slim | 2 
 plugins/suppliers/public/javascripts/views/consumer-view.tag.slim | 12 
 plugins/suppliers/public/javascripts/views/product-modal.tag.slim | 25 
 plugins/suppliers/public/javascripts/views/product-page.tag.slim | 6 
 test/unit/mail_queuer_test.rb | 142 


diff --git a/Gemfile.lock b/Gemfile.lock
index e38ece4cc54f9d3d507bf5cf8d97c2939b22721d..ecfde0a40d9c2c9cc4934ea7a3040887fe8a842e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,16 +1,9 @@
 GIT
   remote: git://github.com/coletivoEITA/acts_as_solr_reloaded.git
-  revision: fb797353c7358b6b1b045d866a517409b5b29306
-  ref: fb79735
+  revision: a04ff0c8b48e6c128166bc9e95b9ab1b865f45e8
+  ref: a04ff0c
   specs:
     acts_as_solr_reloaded (1.6.0)
-
-GIT
-  remote: git://github.com/coletivoEITA/i18n-js.git
-  revision: b47088c555fbe057bb70ec871677a9a1848b22e4
-  specs:
-    i18n-js (3.0.0.rc11)
-      i18n (~> 0.6)
 
 PATH
   remote: vendor/contacts
@@ -171,11 +164,12 @@       activerecord (>= 3.2, < 5)
     addressable (2.5.1)
       public_suffix (~> 2.0, >= 2.0.2)
     ansi (1.5.0)
-    api-pagination (4.5.2)
+    api-pagination (4.6.3)
     arel (6.0.4)
     assets_live_compile (0.2.1)
       activesupport (>= 3.1)
       rails (>= 3.1)
+    attr_required (1.0.1)
     axiom-types (0.1.1)
       descendants_tracker (~> 0.0.4)
       ice_nine (~> 0.11.0)
@@ -194,9 +188,9 @@       erubis (>= 2.6.6)
       rack (>= 0.9.0)
     binding_of_caller (0.7.2)
       debug_inspector (>= 0.0.1)
-    browser (2.3.0)
+    browser (2.4.0)
     builder (3.2.3)
-    capybara (2.13.0)
+    capybara (2.14.0)
       addressable
       mime-types (>= 1.16)
       nokogiri (>= 1.3.3)
@@ -204,14 +198,14 @@       rack (>= 1.0.0)
       rack-test (>= 0.5.4)
       xpath (~> 2.0)
     charlock_holmes (0.7.3)
-    childprocess (0.6.3)
+    childprocess (0.7.0)
       ffi (~> 1.0, >= 1.0.11)
     chronic (0.10.2)
     coderay (1.1.1)
     coercible (1.0.0)
       descendants_tracker (~> 0.0.1)
     concurrent-ruby (1.0.5)
-    css_parser (1.4.9)
+    css_parser (1.5.0)
       addressable
     cucumber (1.3.20)
       builder (>= 2.1.2)
@@ -227,12 +221,12 @@       nokogiri (~> 1.5)
       railties (>= 3, < 5.1)
     daemons (1.2.4)
     dalli (2.7.6)
-    database_cleaner (1.5.3)
-    debug_inspector (0.0.2)
-    delayed_job (4.1.2)
-      activesupport (>= 3.0, < 5.1)
-    delayed_job_active_record (4.1.1)
-      activerecord (>= 3.0, < 5.1)
+    database_cleaner (1.6.1)
+    debug_inspector (0.0.3)
+    delayed_job (4.1.3)
+      activesupport (>= 3.0, < 5.2)
+    delayed_job_active_record (4.1.2)
+      activerecord (>= 3.0, < 5.2)
       delayed_job (>= 3.0, < 5)
     descendants_tracker (0.0.4)
       thread_safe (~> 0.3, >= 0.3.1)
@@ -240,7 +234,7 @@     diff-lcs (1.3)
     diffy (3.2.0)
     domain_name (0.5.20170404)
       unf (>= 0.0.5, < 1.0.0)
-    dotenv (2.2.0)
+    dotenv (2.2.1)
     eita-jrails (0.10.1)
       actionpack (>= 3.1.0)
       activesupport (>= 3.0.0)
@@ -250,13 +244,25 @@     exception_notification (4.0.1)
       actionmailer (>= 3.0.4)
       activesupport (>= 3.0.4)
     execjs (2.7.0)
+    facebook-signed-request (0.2.7)
     faraday (0.11.0)
       multipart-post (>= 1.2, < 3)
     fast_blank (1.0.0)
     fast_gettext (0.9.2)
+    fb_graph (2.7.17)
+      httpclient (>= 2.4)
+      multi_json (>= 1.3)
+      rack-oauth2 (>= 0.14.4)
+      tzinfo
+    fb_graph2 (0.9.1)
+      activesupport (>= 3.2)
+      httpclient (>= 2.4)
+      multi_json
+      rack-oauth2 (>= 1.1)
+      url_safe_base64
     ffi (1.9.18)
     flamegraph (0.9.5)
-    geocoder (1.4.3)
+    geocoder (1.4.4)
     get_process_mem (0.2.1)
     gettext (3.2.2)
       locale (>= 2.0.5)
@@ -264,8 +270,8 @@       text (>= 1.3.0)
     gherkin (2.12.2)
       multi_json (~> 1.3)
     git-version-bump (0.15.1)
-    globalid (0.3.7)
-      activesupport (>= 4.1.0)
+    globalid (0.4.0)
+      activesupport (>= 4.2.0)
     grape (0.19.2)
       activesupport
       builder
@@ -279,41 +285,50 @@       virtus (>= 1.0.0)
     grape-entity (0.4.8)
       activesupport
       multi_json (>= 1.3.2)
-    grape_logging (1.4.0)
+    grape_logging (1.5.0)
       grape
-    haml (4.0.7)
+    haml (5.0.1)
+      temple (>= 0.8.0)
       tilt
     haml2slim (0.4.7)
       haml (>= 3.0)
       nokogiri
       ruby_parser
     hashie (3.5.5)
-    html2haml (2.1.0)
+    html2haml (2.2.0)
       erubis (~> 2.7.0)
-      haml (~> 4.0)
+      haml (>= 4.0, < 6)
       nokogiri (>= 1.6.0)
       ruby_parser (~> 3.5)
     htmlentities (4.3.4)
     http-cookie (1.0.3)
       domain_name (~> 0.5)
+    httpclient (2.8.3)
     i18n (0.8.1)
+    i18n-js (3.0.0)
+      i18n (~> 0.6, >= 0.6.6)
     ice_nine (0.11.2)
     js-routes (1.2.6)
       railties (>= 3.2)
       sprockets-rails
-    json (2.0.4)
+    json (2.1.0)
+    jsonify (0.3.1)
+      multi_json (~> 1.0)
+    jsonify-rails (0.3.2)
+      actionpack
+      jsonify (< 0.4.0)
     jwt (1.5.6)
     kgio (2.11.0)
     launchy (2.4.3)
       addressable (~> 2.3)
-    libv8 (3.16.14.17)
+    libv8 (3.16.14.19)
     liquid (4.0.0)
     locale (2.1.2)
     loofah (2.0.3)
       nokogiri (>= 1.5.9)
     magic (0.2.9)
       ffi (>= 0.6.3)
-    mail (2.6.4)
+    mail (2.6.5)
       mime-types (>= 1.16, < 4)
     mailgun_rails (0.9.0)
       actionmailer (>= 3.2.13)
@@ -325,7 +340,7 @@     metaclass (0.0.4)
     method_source (0.8.2)
     mime-types (2.99.3)
     mini_portile2 (2.1.0)
-    minitest (5.10.1)
+    minitest (5.10.2)
     minitest-reporters (1.1.14)
       ansi
       builder
@@ -341,22 +356,24 @@     mustermann (1.0.0)
     mustermann-grape (1.0.0)
       mustermann (~> 1.0.0)
     netrc (0.11.0)
-    newrelic_rpm (3.18.1.330)
+    newrelic_rpm (4.2.0.334)
     nokogiri (1.6.8.1)
       mini_portile2 (~> 2.1.0)
-    oauth (0.5.1)
+    oauth (0.5.3)
     oauth2 (1.3.1)
       faraday (>= 0.8, < 0.12)
       jwt (~> 1.0)
       multi_json (~> 1.3)
       multi_xml (~> 0.5)
       rack (>= 1.2, < 3)
+    oj (2.17.5)
+    oj_mimic_json (1.0.1)
     omniauth (1.6.1)
       hashie (>= 3.4.6, < 3.6.0)
       rack (>= 1.6.2, < 3)
     omniauth-facebook (4.0.0)
       omniauth-oauth2 (~> 1.2)
-    omniauth-github (1.2.3)
+    omniauth-github (1.3.0)
       omniauth (~> 1.5)
       omniauth-oauth2 (>= 1.4.0, < 2.0)
     omniauth-google-oauth2 (0.4.1)
@@ -375,14 +392,15 @@       omniauth-oauth (~> 1.1)
       rack
     pg (0.20.0)
     pothoven-attachment_fu (3.2.18)
-    power_assert (1.0.1)
-    premailer (1.10.0)
-      css_parser (>= 1.4.9)
+    power_assert (1.0.2)
+    premailer (1.10.4)
+      addressable
+      css_parser (>= 1.4.10)
       htmlentities (>= 4.0.0)
-    premailer-rails (1.9.5)
+    premailer-rails (1.9.6)
       actionmailer (>= 3, < 6)
       premailer (~> 1.7, >= 1.7.9)
-    protected_attributes (1.1.3)
+    protected_attributes (1.1.4)
       activemodel (>= 4.0.1, < 5.0)
     pry (0.10.4)
       coderay (~> 1.1.0)
@@ -390,18 +408,25 @@       method_source (~> 0.8.1)
       slop (~> 3.4)
     public_suffix (2.0.5)
     puma (3.8.2)
-    puma_worker_killer (0.0.7)
+    puma_worker_killer (0.1.0)
       get_process_mem (~> 0.2)
       puma (>= 2.7, < 4)
-    rack (1.6.5)
+    rack (1.6.8)
     rack-accept (0.4.5)
       rack (>= 0.4)
     rack-contrib (1.4.0)
       git-version-bump (~> 0.15)
       rack (~> 1.4)
     rack-cors (0.4.1)
+    rack-oauth2 (1.6.2)
+      activesupport (>= 2.3)
+      attr_required (>= 0.0.5)
+      httpclient (>= 2.4)
+      multi_json (>= 1.3.6)
+      rack (>= 1.1)
     rack-test (0.6.3)
       rack (>= 1.0)
+    rack-timeout (0.4.2)
     rails (4.2.8)
       actionmailer (= 4.2.8)
       actionpack (= 4.2.8)
@@ -432,22 +457,23 @@       rake (>= 0.8.7)
       thor (>= 0.18.1, < 2.0)
     raindrops (0.18.0)
     rake (12.0.0)
+    rakismet (1.5.3)
     redis (3.3.3)
     redis-actionpack (5.0.1)
       actionpack (>= 4.0, < 6)
       redis-rack (>= 1, < 3)
       redis-store (>= 1.1.0, < 1.4.0)
-    redis-activesupport (5.0.1)
+    redis-activesupport (5.0.2)
       activesupport (>= 3, < 6)
-      redis-store (~> 1.2.0)
-    redis-rack (1.6.0)
-      rack (~> 1.5)
-      redis-store (~> 1.2.0)
-    redis-rails (5.0.1)
-      redis-actionpack (~> 5.0.0)
-      redis-activesupport (~> 5.0.0)
-      redis-store (~> 1.2.0)
-    redis-store (1.2.0)
+      redis-store (~> 1.3.0)
+    redis-rack (2.0.2)
+      rack (>= 1.5, < 3)
+      redis-store (>= 1.2, < 1.4)
+    redis-rails (5.0.2)
+      redis-actionpack (>= 5.0, < 6)
+      redis-activesupport (>= 5.0, < 6)
+      redis-store (>= 1.2, < 2)
+    redis-store (1.3.0)
       redis (>= 2.2)
     ref (2.0.0)
     rest-client (1.8.0)
@@ -458,36 +484,36 @@     riot_js-rails (0.7.1)
       execjs (~> 2)
       rails (>= 3.0, < 6.0)
     rmagick (2.16.0)
-    rollbar (2.14.0)
+    rollbar (2.14.1)
       multi_json
-    rspec (3.5.0)
-      rspec-core (~> 3.5.0)
-      rspec-expectations (~> 3.5.0)
-      rspec-mocks (~> 3.5.0)
-    rspec-core (3.5.4)
-      rspec-support (~> 3.5.0)
-    rspec-expectations (3.5.0)
+    rspec (3.6.0)
+      rspec-core (~> 3.6.0)
+      rspec-expectations (~> 3.6.0)
+      rspec-mocks (~> 3.6.0)
+    rspec-core (3.6.0)
+      rspec-support (~> 3.6.0)
+    rspec-expectations (3.6.0)
       diff-lcs (>= 1.2.0, < 2.0)
-      rspec-support (~> 3.5.0)
-    rspec-mocks (3.5.0)
+      rspec-support (~> 3.6.0)
+    rspec-mocks (3.6.0)
       diff-lcs (>= 1.2.0, < 2.0)
-      rspec-support (~> 3.5.0)
-    rspec-rails (3.5.2)
+      rspec-support (~> 3.6.0)
+    rspec-rails (3.6.0)
       actionpack (>= 3.0)
       activesupport (>= 3.0)
       railties (>= 3.0)
-      rspec-core (~> 3.5.0)
-      rspec-expectations (~> 3.5.0)
-      rspec-mocks (~> 3.5.0)
-      rspec-support (~> 3.5.0)
-    rspec-support (3.5.0)
+      rspec-core (~> 3.6.0)
+      rspec-expectations (~> 3.6.0)
+      rspec-mocks (~> 3.6.0)
+      rspec-support (~> 3.6.0)
+    rspec-support (3.6.0)
     ruby-feedparser (0.9.4)
       magic
     ruby-progressbar (1.8.1)
-    ruby_parser (3.8.4)
+    ruby_parser (3.9.0)
       sexp_processor (~> 4.1)
     rubyzip (1.0.0)
-    sass (3.4.23)
+    sass (3.4.24)
     sass-rails (5.0.6)
       railties (>= 4.0.0, < 6)
       sass (~> 3.1)
@@ -498,12 +524,12 @@     selenium-webdriver (2.53.4)
       childprocess (~> 0.5)
       rubyzip (~> 1.0)
       websocket (~> 1.0)
-    sexp_processor (4.8.0)
-    slim (3.0.7)
-      temple (~> 0.7.6)
+    sexp_processor (4.9.0)
+    slim (3.0.8)
+      temple (>= 0.7.6, < 0.9)
       tilt (>= 1.3.3, < 2.1)
     slop (3.6.0)
-    spring (2.0.1)
+    spring (2.0.2)
       activesupport (>= 4.2)
     sprockets (3.7.1)
       concurrent-ruby (~> 1.0)
@@ -517,8 +543,8 @@       actionpack (>= 3.0)
       activesupport (>= 3.0)
       sprockets (>= 2.8, < 4.0)
     stackprof (0.2.10)
-    temple (0.7.7)
-    test-unit (3.2.3)
+    temple (0.8.0)
+    test-unit (3.2.4)
       power_assert
     text (1.3.1)
     therubyracer (0.12.3)
@@ -533,8 +559,8 @@     uglifier (3.2.0)
       execjs (>= 0.3.0, < 3)
     unf (0.1.4)
       unf_ext
-    unf_ext (0.0.7.3)
-    unicode (0.4.4.2)
+    unf_ext (0.0.7.4)
+    unicode (0.4.4.4)
     unicorn (4.9.0)
       kgio (~> 2.6)
       rack
@@ -542,6 +568,7 @@       raindrops (~> 0.7)
     unicorn-worker-killer (0.4.4)
       get_process_mem (~> 0)
       unicorn (>= 4, < 6)
+    url_safe_base64 (0.2.2)
     utf8-cleaner (0.2.5)
       activesupport
     virtus (1.0.5)
@@ -555,7 +582,7 @@       chronic (>= 0.6.3)
     will-paginate-i18n (0.1.15)
     will_paginate (3.0.12)
     wirble (0.1.3)
-    xpath (2.0.0)
+    xpath (2.1.0)
       nokogiri (~> 1.3)
 
 PLATFORMS
@@ -598,8 +625,11 @@   dotenv
   eita-jrails (~> 0.10.0)
   exception_notification (~> 4.0.1)
   ezcrypto (= 0.0.0)!
+  facebook-signed-request
   fast_blank
   fast_gettext (~> 0.9)
+  fb_graph
+  fb_graph2
   flamegraph
   gdata (> 0.0.0)!
   geocoder
@@ -610,9 +640,10 @@   grape_logging
   haml2slim
   honeypot (= 0.0.0)!
   html2haml
-  i18n-js!
+  i18n-js
   i18n_deprecation (= 0.0.0)!
   js-routes (= 1.2.6)
+  jsonify-rails
   kandadaboggu-vote_fu (> 0.0.0)!
   launchy
   liquid (>= 3.0.3)
@@ -625,6 +656,8 @@   mocha (~> 1.1.0)
   monkey_patches (= 0.0.0)!
   newrelic_rpm
   nokogiri (~> 1.6.0)
+  oj (~> 2.0)
+  oj_mimic_json
   omniauth
   omniauth-facebook
   omniauth-github
@@ -639,11 +672,13 @@   pry
   puma_worker_killer
   rack-contrib
   rack-cors
+  rack-timeout
   rails (~> 4.2.7)
   rails-observers
   rails_autolink (~> 1.1.5)
   rails_rcov (= 0.0.0)!
   rake
+  rakismet (~> 1.5.0)
   recaptcha (> 0.0.0)!
   redis-rails
   rest-client (~> 1.6)




diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 372ca4be45a3e17b868c696b59fe90f5396d7acb..e76ddb74a4a1cf0e15eb6ca38239915b046744a0 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -110,7 +110,7 @@   before_filter :set_locale
   def set_locale
     FastGettext.available_locales = environment.available_locales
     FastGettext.default_locale = environment.default_locale || :en_US
-    FastGettext.locale = ENV['LANG'] || params[:lang] || session[:lang] || environment.default_locale || request.env['HTTP_ACCEPT_LANGUAGE'] || :en_US
+    FastGettext.locale = params[:lang] || session[:lang] || ENV['LANG'] || environment.default_locale || request.env['HTTP_ACCEPT_LANGUAGE'] || :en_US
     I18n.locale = FastGettext.locale
     I18n.default_locale = FastGettext.default_locale
     if params[:lang]




diff --git a/app/mailers/mail_queuer.rb b/app/mailers/mail_queuer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3d44e79f724180eb04c1b41927c88486123008d1
--- /dev/null
+++ b/app/mailers/mail_queuer.rb
@@ -0,0 +1,116 @@
+module MailQueuer
+
+  extend ActiveSupport::Concern
+
+  included do
+    alias_method :deliver_now, :deliver
+    prepend InstanceMethods
+  end
+
+  class Job < ActiveJob::Base
+    queue_as :default
+
+    ##
+    #
+    def self.schedule message, options = {}
+      delivery_method = ApplicationMailer.delivery_methods.find{ |n, k| k == message.delivery_method.class }.first
+      delivery_method_options = message.delivery_method.settings
+
+      set(options).perform_later message.encoded, message.bcc, delivery_method.to_s, delivery_method_options.to_yaml
+    end
+
+    ##
+    # Mail delivery
+    #
+    def perform message, bcc, delivery_method, delivery_method_options
+      m = Mail.read_from_string message
+      m.bcc = bcc
+      ApplicationMailer.wrap_delivery_behavior m, delivery_method.to_sym, YAML.load(delivery_method_options)
+      m.deliver_now
+    end
+  end
+
+  module InstanceMethods
+    def deliver
+      message    = nil
+      last_sched = MailSchedule.last
+      last_sched.with_lock do
+        if last_sched != MailSchedule.last
+          message = deliver_now
+        else
+          message = deliver_schedule last_sched
+        end
+      end
+      message
+    end
+
+    def deliver_schedule last_sched
+      limit   = ENV['MAIL_QUEUER_LIMIT'].to_i - 1
+      orig_to = Array(to).dup
+      orig_cc = Array(cc).dup
+      dests   = {
+        to:  Array(self.to),
+        cc:  Array(self.cc),
+        bcc: Array(self.bcc),
+      }
+
+      loop do
+        # mailers don't like emails without :to,
+        # so fill one if not present
+        dests[:to] = [orig_to.first] if dests[:to].blank?
+
+        dest_count = dests[:to].size + dests[:cc].size + dests[:bcc].size
+        # dests are changed on email splits, so set it to the remaining values
+        self.to    = dests[:to]
+        self.cc    = dests[:cc]
+        self.bcc   = dests[:bcc]
+
+        ##
+        # The last schedule is outside the quota period
+        #
+        if last_sched.scheduled_to < 1.hour.ago
+          last_sched = MailSchedule.create! dest_count: 0, scheduled_to: Time.now.beginning_of_hour
+        end
+
+        available_limit = limit - last_sched.dest_count
+
+        if dest_count <= available_limit
+          last_sched.update dest_count: last_sched.dest_count + dest_count
+          Job.schedule self, wait_until: last_sched.scheduled_to
+          return self
+
+        # avoid breaking mail which respect the mail limit. Schedule it all to the next hour
+        elsif dest_count <= limit #&& ENV['AVOID_SPLIT']
+          last_sched = MailSchedule.create! dest_count: dest_count, scheduled_to: last_sched.scheduled_to+1.hour
+          Job.schedule self, wait_until: last_sched.scheduled_to
+          return self
+
+        else # dest_count > limit
+          if available_limit == 0
+            available_limit = limit
+            last_sched = MailSchedule.create! dest_count: limit, scheduled_to: last_sched.scheduled_to+1.hour
+          else
+            # reuse current schedule
+            last_sched.update dest_count: limit # limit = last.sched.dest_count + available_limit
+          end
+
+          # needs to preserve replies when spliting the email
+          self.reply_to = orig_to + orig_cc if self.reply_to.blank?
+
+          ##
+          # start sending :to, followed by :cc, and so :bcc creating new schedules as needed
+          #
+          [:to, :cc, :bcc].each do |field|
+            next self[field] = [] if available_limit == 0
+
+            self[field] = dests[field].shift(available_limit)
+            available_limit -= self.send(field).size
+          end
+
+          Job.schedule self, wait_until: last_sched.scheduled_to
+        end
+      end
+    end
+
+  end
+end




diff --git a/app/models/mail_schedule.rb b/app/models/mail_schedule.rb
new file mode 100644
index 0000000000000000000000000000000000000000..40a0bc211d70194e143d0f9facd2f5b47a23a9a1
--- /dev/null
+++ b/app/models/mail_schedule.rb
@@ -0,0 +1,3 @@
+class MailSchedule < ApplicationRecord
+
+end




diff --git a/config/Gemfile b/config/Gemfile
index 6d0efd2ad41ff170260b91c2746f34df27f9430a..b79f99bb8b70ff03a2f71bd18833a983819e11de 100644
--- a/config/Gemfile
+++ b/config/Gemfile
@@ -46,8 +46,9 @@
 platform :ruby do
   gem 'unicode'
   group :performance do
+
     # FIXME: stack level too deep
-    gem 'oj'
+    gem 'oj', '~> 2.0'
     gem 'oj_mimic_json'
 
     gem 'fast_blank'




diff --git a/config/application.rb b/config/application.rb
index 0c05a1b212aca11b1f4eafda140f2cdb6c0f2a45..4736b31faa3c97510e5befae3118df51f5b32056 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -89,6 +89,11 @@
     # Configure sensitive parameters which will be filtered from the log file.
     config.filter_parameters += [:password]
 
+    ##
+    # Configure ActiveJob
+    #
+    config.active_job.queue_adapter = :delayed_job
+
     # Enable escaping HTML in JSON.
     ActiveSupport::JSON::Encoding.escape_html_entities_in_json = true
 




diff --git a/config/initializers/mail_queuer.rb b/config/initializers/mail_queuer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c5c8f356067991582a7433e8ff8210ce8140f4d7
--- /dev/null
+++ b/config/initializers/mail_queuer.rb
@@ -0,0 +1,5 @@
+if ENV['MAIL_QUEUER']
+
+  Mail::Message.include MailQueuer if ENV['MAIL_QUEUER']
+
+end




diff --git a/db/migrate/20170701160657_add_mail_schedules.rb b/db/migrate/20170701160657_add_mail_schedules.rb
new file mode 100644
index 0000000000000000000000000000000000000000..781a8631996ef2bce5bb05c31caaacf964151e48
--- /dev/null
+++ b/db/migrate/20170701160657_add_mail_schedules.rb
@@ -0,0 +1,9 @@
+class AddMailSchedules < ActiveRecord::Migration
+  def change
+    create_table :mail_schedules do |t|
+      t.integer :dest_count
+      t.datetime :scheduled_to
+    end
+    MailSchedule.create(dest_count: 0, scheduled_to: Time.now)
+  end
+end




diff --git a/db/schema.rb b/db/schema.rb
index 73ca00d75773d2c9eb45c61d954cbcb8eebdd667..415c0888ac1217b217d646495c5efdb61e2e72ac 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@ # you'll amass, the slower it'll run and the greater likelihood for issues).
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20170401104432) do
+ActiveRecord::Schema.define(version: 20170701160657) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -27,15 +27,15 @@   end
 
   create_table "action_tracker", force: :cascade do |t|
     t.integer  "user_id"
-    t.string   "user_type"
+    t.string   "user_type",      limit: 255
     t.integer  "target_id"
-    t.string   "target_type"
+    t.string   "target_type",    limit: 255
     t.text     "params"
-    t.string   "verb"
+    t.string   "verb",           limit: 255
     t.datetime "created_at"
     t.datetime "updated_at"
-    t.integer  "comments_count", default: 0
-    t.boolean  "visible",        default: true
+    t.integer  "comments_count",             default: 0
+    t.boolean  "visible",                    default: true
   end
 
   add_index "action_tracker", ["target_id", "target_type"], name: "index_action_tracker_on_dispatcher_id_and_dispatcher_type", using: :btree
@@ -48,7 +48,7 @@     t.integer "profile_id"
   end
 
   add_index "action_tracker_notifications", ["action_tracker_id"], name: "index_action_tracker_notifications_on_action_tracker_id", using: :btree
-  add_index "action_tracker_notifications", ["profile_id", "action_tracker_id"], name: "index_action_tracker_notif_on_prof_id_act_tracker_id", unique: true, using: :btree
+  add_index "action_tracker_notifications", ["profile_id", "action_tracker_id"], name: "index_action_tracker_notifications_on_profile_id_and_action_tra", unique: true, using: :btree
   add_index "action_tracker_notifications", ["profile_id"], name: "index_action_tracker_notifications_on_profile_id", using: :btree
 
   create_table "article_followers", force: :cascade do |t|
@@ -71,9 +71,9 @@
   create_table "article_versions", force: :cascade do |t|
     t.integer  "article_id"
     t.integer  "version"
-    t.string   "name"
-    t.string   "slug"
-    t.text     "path",                 default: ""
+    t.string   "name",                 limit: 255
+    t.string   "slug",                 limit: 255
+    t.text     "path",                             default: ""
     t.integer  "parent_id"
     t.text     "body"
     t.text     "abstract"
@@ -82,35 +82,35 @@     t.datetime "updated_at"
     t.datetime "created_at"
     t.integer  "last_changed_by_id"
     t.integer  "size"
-    t.string   "content_type"
-    t.string   "filename"
+    t.string   "content_type",         limit: 255
+    t.string   "filename",             limit: 255
     t.integer  "height"
     t.integer  "width"
-    t.string   "versioned_type"
+    t.string   "versioned_type",       limit: 255
     t.integer  "comments_count"
-    t.boolean  "advertise",            default: true
-    t.boolean  "published",            default: true
+    t.boolean  "advertise",                        default: true
+    t.boolean  "published",                        default: true
     t.datetime "start_date"
     t.datetime "end_date"
-    t.integer  "children_count",       default: 0
-    t.boolean  "accept_comments",      default: true
+    t.integer  "children_count",                   default: 0
+    t.boolean  "accept_comments",                  default: true
     t.integer  "reference_article_id"
     t.text     "setting"
-    t.boolean  "notify_comments",      default: false
-    t.integer  "hits",                 default: 0
+    t.boolean  "notify_comments",                  default: false
+    t.integer  "hits",                             default: 0
     t.datetime "published_at"
-    t.string   "source"
-    t.boolean  "highlighted",          default: false
-    t.string   "external_link"
-    t.boolean  "thumbnails_processed", default: false
-    t.boolean  "is_image",             default: false
+    t.string   "source",               limit: 255
+    t.boolean  "highlighted",                      default: false
+    t.string   "external_link",        limit: 255
+    t.boolean  "thumbnails_processed",             default: false
+    t.boolean  "is_image",                         default: false
     t.integer  "translation_of_id"
-    t.string   "language"
-    t.string   "source_name"
+    t.string   "language",             limit: 255
+    t.string   "source_name",          limit: 255
     t.integer  "license_id"
     t.integer  "image_id"
     t.integer  "position"
-    t.integer  "spam_comments_count",  default: 0
+    t.integer  "spam_comments_count",              default: 0
     t.integer  "author_id"
     t.integer  "created_by_id"
   end
@@ -122,9 +122,9 @@   add_index "article_versions", ["path"], name: "index_article_versions_on_path", using: :btree
   add_index "article_versions", ["published_at", "id"], name: "index_article_versions_on_published_at_and_id", using: :btree
 
   create_table "articles", force: :cascade do |t|
-    t.string   "name"
-    t.string   "slug"
-    t.text     "path",                 default: ""
+    t.string   "name",                 limit: 255
+    t.string   "slug",                 limit: 255
+    t.text     "path",                             default: ""
     t.integer  "parent_id"
     t.text     "body"
     t.text     "abstract"
@@ -133,48 +133,47 @@     t.datetime "updated_at"
     t.datetime "created_at"
     t.integer  "last_changed_by_id"
     t.integer  "version"
-    t.string   "type"
+    t.string   "type",                 limit: 255
     t.integer  "size"
-    t.string   "content_type"
-    t.string   "filename"
+    t.string   "content_type",         limit: 255
+    t.string   "filename",             limit: 255
     t.integer  "height"
     t.integer  "width"
-    t.integer  "comments_count",       default: 0
-    t.boolean  "advertise",            default: true
-    t.boolean  "published",            default: true
+    t.integer  "comments_count",                   default: 0
+    t.boolean  "advertise",                        default: true
+    t.boolean  "published",                        default: true
     t.datetime "start_date"
     t.datetime "end_date"
-    t.integer  "children_count",       default: 0
-    t.boolean  "accept_comments",      default: true
+    t.integer  "children_count",                   default: 0
+    t.boolean  "accept_comments",                  default: true
     t.integer  "reference_article_id"
     t.text     "setting"
-    t.boolean  "notify_comments",      default: true
-    t.integer  "hits",                 default: 0
+    t.boolean  "notify_comments",                  default: true
+    t.integer  "hits",                             default: 0
     t.datetime "published_at"
-    t.string   "source"
-    t.boolean  "highlighted",          default: false
-    t.string   "external_link"
-    t.boolean  "thumbnails_processed", default: false
-    t.boolean  "is_image",             default: false
+    t.string   "source",               limit: 255
+    t.boolean  "highlighted",                      default: false
+    t.string   "external_link",        limit: 255
+    t.boolean  "thumbnails_processed",             default: false
+    t.boolean  "is_image",                         default: false
     t.integer  "translation_of_id"
-    t.string   "language"
-    t.string   "source_name"
+    t.string   "language",             limit: 255
+    t.string   "source_name",          limit: 255
     t.integer  "license_id"
     t.integer  "image_id"
     t.integer  "position"
-    t.integer  "spam_comments_count",  default: 0
+    t.integer  "spam_comments_count",              default: 0
     t.integer  "author_id"
     t.integer  "created_by_id"
-    t.boolean  "show_to_followers",    default: true
-    t.integer  "followers_count",      default: 0
-    t.boolean  "archived",             default: false
-    t.string   "editor",               default: "tiny_mce", null: false
+    t.boolean  "show_to_followers",                default: true
+    t.boolean  "archived",                         default: false
+    t.integer  "followers_count",                  default: 0
+    t.string   "editor",                           default: "tiny_mce", null: false
   end
 
   add_index "articles", ["comments_count"], name: "index_articles_on_comments_count", using: :btree
   add_index "articles", ["created_at"], name: "index_articles_on_created_at", using: :btree
   add_index "articles", ["hits"], name: "index_articles_on_hits", using: :btree
-  add_index "articles", ["name"], name: "index_articles_on_name", using: :btree
   add_index "articles", ["parent_id"], name: "index_articles_on_parent_id", using: :btree
   add_index "articles", ["path", "profile_id"], name: "index_articles_on_path_and_profile_id", using: :btree
   add_index "articles", ["path"], name: "index_articles_on_path", using: :btree
@@ -196,19 +195,19 @@   add_index "articles_categories", ["article_id"], name: "index_articles_categories_on_article_id", using: :btree
   add_index "articles_categories", ["category_id"], name: "index_articles_categories_on_category_id", using: :btree
 
   create_table "blocks", force: :cascade do |t|
-    t.string   "title"
+    t.string   "title",           limit: 255
     t.integer  "box_id"
-    t.string   "type"
+    t.string   "type",            limit: 255
     t.text     "settings"
     t.integer  "position"
-    t.boolean  "enabled",         default: true
+    t.boolean  "enabled",                     default: true
     t.datetime "created_at"
     t.datetime "updated_at"
     t.datetime "fetched_at"
-    t.boolean  "mirror",          default: false
+    t.boolean  "mirror",                      default: false
     t.integer  "mirror_block_id"
     t.integer  "observers_id"
-    t.string   "subtitle",        default: ""
+    t.string   "subtitle",                    default: ""
   end
 
   add_index "blocks", ["box_id"], name: "index_blocks_on_box_id", using: :btree
@@ -217,33 +216,70 @@   add_index "blocks", ["fetched_at"], name: "index_blocks_on_fetched_at", using: :btree
   add_index "blocks", ["type"], name: "index_blocks_on_type", using: :btree
 
   create_table "boxes", force: :cascade do |t|
-    t.string  "owner_type"
+    t.string  "owner_type", limit: 255
     t.integer "owner_id"
     t.integer "position"
   end
 
-  add_index "boxes", ["owner_id", "owner_type"], name: "index_boxes_on_owner_type_and_owner_id", using: :btree
+  add_index "boxes", ["owner_type", "owner_id"], name: "index_boxes_on_owner_type_and_owner_id", using: :btree
+
+  create_table "br_nivel2", id: false, force: :cascade do |t|
+    t.string "cidade", limit: 255
+    t.float  "lat"
+    t.float  "lng"
+  end
+
+  create_table "bsc_plugin_contracts", force: :cascade do |t|
+    t.string   "client_name",         limit: 255
+    t.integer  "client_type"
+    t.integer  "business_type"
+    t.string   "state",               limit: 255
+    t.string   "city",                limit: 255
+    t.integer  "status",                          default: 0
+    t.integer  "number_of_producers",             default: 0
+    t.datetime "supply_start"
+    t.datetime "supply_end"
+    t.text     "annotations"
+    t.integer  "bsc_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "bsc_plugin_contracts_enterprises", id: false, force: :cascade do |t|
+    t.integer "contract_id"
+    t.integer "enterprise_id"
+  end
+
+  create_table "bsc_plugin_sales", force: :cascade do |t|
+    t.integer  "product_id",  null: false
+    t.integer  "contract_id", null: false
+    t.integer  "quantity",    null: false
+    t.decimal  "price"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
 
   create_table "categories", force: :cascade do |t|
-    t.string  "name"
-    t.string  "slug"
-    t.text    "path",                           default: ""
+    t.string  "name",                 limit: 255
+    t.string  "slug",                 limit: 255
+    t.text    "path",                             default: ""
     t.integer "environment_id"
     t.integer "parent_id"
-    t.string  "type"
+    t.string  "type",                 limit: 255
     t.float   "lat"
     t.float   "lng"
-    t.boolean "display_in_menu",                default: false
-    t.integer "children_count",                 default: 0
-    t.boolean "accept_products",                default: true
+    t.boolean "display_in_menu",                  default: false
+    t.integer "children_count",                   default: 0
+    t.boolean "accept_products",                  default: true
     t.integer "image_id"
-    t.string  "acronym"
-    t.string  "abbreviation"
-    t.string  "display_color",        limit: 6
+    t.string  "acronym",              limit: 255
+    t.string  "abbreviation",         limit: 255
     t.text    "ancestry"
-    t.boolean "visible_for_articles",           default: true
-    t.boolean "visible_for_profiles",           default: true
-    t.boolean "choosable",                      default: true
+    t.boolean "visible_for_articles",             default: true
+    t.boolean "visible_for_profiles",             default: true
+    t.boolean "choosable",                        default: true
+    t.string  "display_color",        limit: 6
+    t.string  "uuid"
   end
 
   add_index "categories", ["parent_id"], name: "index_categories_on_parent_id", using: :btree
@@ -258,17 +294,17 @@   add_index "categories_profiles", ["category_id"], name: "index_categories_profiles_on_category_id", using: :btree
   add_index "categories_profiles", ["profile_id"], name: "index_categories_profiles_on_profile_id", using: :btree
 
   create_table "certifiers", force: :cascade do |t|
-    t.string   "name",           null: false
+    t.string   "name",           limit: 255, null: false
     t.text     "description"
-    t.string   "link"
+    t.string   "link",           limit: 255
     t.integer  "environment_id"
     t.datetime "created_at"
     t.datetime "updated_at"
   end
 
   create_table "chat_messages", force: :cascade do |t|
-    t.integer  "from_id",    null: false
-    t.integer  "to_id",      null: false
+    t.integer  "from_id"
+    t.integer  "to_id"
     t.text     "body"
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
@@ -286,22 +322,60 @@     t.datetime "created_at"
     t.datetime "updated_at"
   end
 
-  add_index "circles", ["person_id", "name", "profile_type"], name: "circles_composite_key_index", unique: true, using: :btree
+  add_index "circles", ["person_id", "name"], name: "circles_composite_key_index", unique: true, using: :btree
+
+  create_table "comment_classification_plugin_comment_label_user", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.integer  "comment_id"
+    t.integer  "label_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "comment_classification_plugin_comment_status_user", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.integer  "comment_id"
+    t.integer  "status_id"
+    t.text     "reason"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "comment_classification_plugin_labels", force: :cascade do |t|
+    t.string   "name",       limit: 255
+    t.string   "color",      limit: 255
+    t.boolean  "enabled",                default: true
+    t.integer  "owner_id"
+    t.string   "owner_type", limit: 255
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "comment_classification_plugin_statuses", force: :cascade do |t|
+    t.string   "name",          limit: 255
+    t.boolean  "enabled",                   default: true
+    t.boolean  "enable_reason",             default: true
+    t.integer  "owner_id"
+    t.string   "owner_type",    limit: 255
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
 
   create_table "comments", force: :cascade do |t|
-    t.string   "title"
+    t.string   "title",       limit: 255
     t.text     "body"
     t.integer  "source_id"
     t.integer  "author_id"
-    t.string   "name"
-    t.string   "email"
+    t.string   "name",        limit: 255
+    t.string   "email",       limit: 255
     t.datetime "created_at"
     t.integer  "reply_of_id"
-    t.string   "ip_address"
+    t.string   "ip_address",  limit: 255
     t.boolean  "spam"
-    t.string   "source_type"
-    t.string   "user_agent"
-    t.string   "referrer"
+    t.string   "source_type", limit: 255
+    t.string   "user_agent",  limit: 255
+    t.string   "referrer",    limit: 255
+    t.integer  "group_id"
     t.text     "settings"
   end
 
@@ -309,8 +383,8 @@   add_index "comments", ["source_id", "spam"], name: "index_comments_on_source_id_and_spam", using: :btree
 
   create_table "contact_lists", force: :cascade do |t|
     t.text     "list"
-    t.string   "error_fetching"
-    t.boolean  "fetched",        default: false
+    t.string   "error_fetching", limit: 255
+    t.boolean  "fetched",                    default: false
     t.datetime "created_at"
     t.datetime "updated_at"
   end
@@ -344,28 +418,112 @@   end
 
   add_index "custom_fields", ["customized_type", "name", "environment_id"], name: "index_custom_field", unique: true, using: :btree
 
+  create_table "custom_forms_plugin_alternatives", force: :cascade do |t|
+    t.string  "label",               limit: 255
+    t.integer "field_id"
+    t.boolean "selected_by_default",             default: false, null: false
+    t.integer "position",                        default: 0
+  end
+
+  create_table "custom_forms_plugin_answers", force: :cascade do |t|
+    t.text    "value"
+    t.integer "field_id"
+    t.integer "submission_id"
+  end
+
+  create_table "custom_forms_plugin_fields", force: :cascade do |t|
+    t.string  "name",          limit: 255
+    t.string  "slug",          limit: 255
+    t.string  "type",          limit: 255
+    t.string  "default_value", limit: 255
+    t.float   "minimum"
+    t.float   "maximum"
+    t.integer "form_id"
+    t.boolean "mandatory",                 default: false
+    t.integer "position",                  default: 0
+    t.string  "show_as",       limit: 255
+  end
+
+  create_table "custom_forms_plugin_forms", force: :cascade do |t|
+    t.string   "name",               limit: 255
+    t.string   "slug",               limit: 255
+    t.text     "description"
+    t.integer  "profile_id"
+    t.datetime "begining"
+    t.datetime "ending"
+    t.boolean  "report_submissions",             default: false
+    t.boolean  "on_membership",                  default: false
+    t.string   "access",             limit: 255
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.boolean  "for_admission",                  default: false
+  end
+
+  create_table "custom_forms_plugin_submissions", force: :cascade do |t|
+    t.string   "author_name",  limit: 255
+    t.string   "author_email", limit: 255
+    t.integer  "profile_id"
+    t.integer  "form_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
   create_table "delayed_jobs", force: :cascade do |t|
-    t.integer  "priority",   default: 0
-    t.integer  "attempts",   default: 0
+    t.integer  "priority",               default: 0
+    t.integer  "attempts",               default: 0
     t.text     "handler"
     t.text     "last_error"
     t.datetime "run_at"
     t.datetime "locked_at"
     t.datetime "failed_at"
-    t.string   "locked_by"
+    t.string   "locked_by",  limit: 255
     t.datetime "created_at"
     t.datetime "updated_at"
-    t.string   "queue"
+    t.string   "queue",      limit: 255
   end
 
   add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
 
+  create_table "delivery_plugin_methods", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.string   "name",                           limit: 255
+    t.text     "description"
+    t.string   "recipient",                      limit: 255
+    t.string   "address_line1",                  limit: 255
+    t.string   "address_line2",                  limit: 255
+    t.string   "postal_code",                    limit: 255
+    t.string   "state",                          limit: 255
+    t.string   "country",                        limit: 255
+    t.string   "delivery_type",                  limit: 255
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.decimal  "fixed_cost"
+    t.decimal  "free_over_price"
+    t.decimal  "distribution_margin_fixed"
+    t.decimal  "distribution_margin_percentage"
+  end
+
+  add_index "delivery_plugin_methods", ["profile_id"], name: "index_distribution_plugin_delivery_methods_on_node_id", using: :btree
+
+  create_table "delivery_plugin_options", force: :cascade do |t|
+    t.integer  "owner_id"
+    t.integer  "delivery_method_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "owner_type",         limit: 255
+  end
+
+  add_index "delivery_plugin_options", ["delivery_method_id"], name: "distribution_plugin_delivery_options_dmid", using: :btree
+  add_index "delivery_plugin_options", ["owner_id", "delivery_method_id"], name: "distribution_plugin_delivery_options_sid_dmid", using: :btree
+  add_index "delivery_plugin_options", ["owner_id"], name: "index_distribution_plugin_delivery_options_on_session_id", using: :btree
+
   create_table "domains", force: :cascade do |t|
-    t.string  "name"
-    t.string  "owner_type"
+    t.string  "name",            limit: 255
+    t.string  "owner_type",      limit: 255
     t.integer "owner_id"
-    t.boolean "is_default",      default: false
-    t.string  "google_maps_key"
+    t.boolean "is_default",                  default: false
+    t.string  "google_maps_key", limit: 255
+    t.boolean "ssl"
   end
 
   add_index "domains", ["is_default"], name: "index_domains_on_is_default", using: :btree
@@ -385,42 +543,43 @@     t.datetime "updated_at"
   end
 
   create_table "environments", force: :cascade do |t|
-    t.string   "name"
-    t.string   "contact_email"
+    t.string   "name",                         limit: 255
+    t.string   "contact_email",                limit: 255
     t.boolean  "is_default"
     t.text     "settings"
     t.text     "design_data"
     t.text     "custom_header"
     t.text     "custom_footer"
-    t.string   "theme",                        default: "default",              null: false
+    t.string   "theme",                        limit: 255, default: "default",              null: false
     t.text     "terms_of_use_acceptance_text"
     t.datetime "created_at"
     t.datetime "updated_at"
-    t.integer  "reports_lower_bound",          default: 0,                      null: false
-    t.string   "redirection_after_login",      default: "keep_on_same_page"
+    t.text     "send_email_plugin_allow_to"
+    t.integer  "reports_lower_bound",                      default: 0,                      null: false
+    t.string   "languages",                    limit: 255
+    t.string   "default_language",             limit: 255
+    t.string   "redirection_after_login",      limit: 255, default: "keep_on_same_page"
     t.text     "signup_welcome_text"
-    t.string   "languages"
-    t.string   "default_language"
-    t.string   "noreply_email"
-    t.string   "redirection_after_signup",     default: "keep_on_same_page"
-    t.string   "date_format",                  default: "month_name_with_year"
-    t.boolean  "enable_feed_proxy",            default: false
+    t.string   "noreply_email",                limit: 255
+    t.string   "redirection_after_signup",     limit: 255, default: "keep_on_same_page"
+    t.string   "date_format",                              default: "month_name_with_year"
+    t.boolean  "enable_feed_proxy",                        default: false
     t.string   "http_feed_proxy"
     t.string   "https_feed_proxy"
-    t.boolean  "disable_feed_ssl",             default: false
+    t.boolean  "disable_feed_ssl",                         default: false
   end
 
   create_table "external_feeds", force: :cascade do |t|
-    t.string   "feed_title"
+    t.string   "feed_title",    limit: 255
     t.datetime "fetched_at"
     t.text     "address"
-    t.integer  "blog_id",                      null: false
-    t.boolean  "enabled",       default: true, null: false
-    t.boolean  "only_once",     default: true, null: false
+    t.integer  "blog_id",                                  null: false
+    t.boolean  "enabled",                   default: true, null: false
+    t.boolean  "only_once",                 default: true, null: false
     t.datetime "created_at"
     t.datetime "updated_at"
     t.text     "error_message"
-    t.integer  "update_errors", default: 0
+    t.integer  "update_errors",             default: 0
   end
 
   add_index "external_feeds", ["blog_id"], name: "index_external_feeds_on_blog_id", using: :btree
@@ -438,11 +597,47 @@   add_index "favorite_enterprise_people", ["enterprise_id"], name: "index_favorite_enterprise_people_on_enterprise_id", using: :btree
   add_index "favorite_enterprise_people", ["person_id", "enterprise_id"], name: "index_favorite_enterprise_people_on_person_id_and_enterprise_id", using: :btree
   add_index "favorite_enterprise_people", ["person_id"], name: "index_favorite_enterprise_people_on_person_id", using: :btree
 
+  create_table "fb_app_plugin_page_tab_configs", force: :cascade do |t|
+    t.string   "page_id",    limit: 255
+    t.text     "config",                 default: "--- {}\n\n"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.integer  "profile_id"
+  end
+
+  add_index "fb_app_plugin_page_tab_configs", ["page_id"], name: "index_fb_app_ecosol_store_plugin_page_configs_on_page_id", using: :btree
+  add_index "fb_app_plugin_page_tab_configs", ["profile_id"], name: "index_fb_app_plugin_page_tab_configs_on_profile_id", using: :btree
+
+  create_table "financial_plugin_transactions", force: :cascade do |t|
+    t.integer  "target_id"
+    t.string   "target_type"
+    t.integer  "target_profile_id"
+    t.integer  "origin_id"
+    t.integer  "order_id"
+    t.integer  "payment_id"
+    t.integer  "payment_method_id"
+    t.integer  "operator_id"
+    t.text     "description"
+    t.string   "direction"
+    t.decimal  "balance"
+    t.decimal  "value"
+    t.datetime "date"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "financial_plugin_transactions", ["operator_id"], name: "index_financial_plugin_transactions_on_operator_id", using: :btree
+  add_index "financial_plugin_transactions", ["order_id"], name: "index_financial_plugin_transactions_on_order_id", using: :btree
+  add_index "financial_plugin_transactions", ["origin_id"], name: "index_financial_plugin_transactions_on_origin_id", using: :btree
+  add_index "financial_plugin_transactions", ["payment_id"], name: "index_financial_plugin_transactions_on_payment_id", using: :btree
+  add_index "financial_plugin_transactions", ["payment_method_id"], name: "index_financial_plugin_transactions_on_payment_method_id", using: :btree
+  add_index "financial_plugin_transactions", ["target_profile_id"], name: "index_financial_plugin_transactions_on_target_profile_id", using: :btree
+
   create_table "friendships", force: :cascade do |t|
     t.integer  "person_id"
     t.integer  "friend_id"
     t.datetime "created_at"
-    t.string   "group"
+    t.string   "group",      limit: 255
   end
 
   add_index "friendships", ["friend_id"], name: "index_friendships_on_friend_id", using: :btree
@@ -451,14 +646,14 @@   add_index "friendships", ["person_id"], name: "index_friendships_on_person_id", using: :btree
 
   create_table "images", force: :cascade do |t|
     t.integer "parent_id"
-    t.string  "content_type"
-    t.string  "filename"
-    t.string  "thumbnail"
+    t.string  "content_type",         limit: 255
+    t.string  "filename",             limit: 255
+    t.string  "thumbnail",            limit: 255
     t.integer "size"
     t.integer "width"
     t.integer "height"
-    t.boolean "thumbnails_processed", default: false
-    t.string  "label",                default: ""
+    t.boolean "thumbnails_processed",             default: false
+    t.string  "label",                            default: ""
     t.integer "owner_id"
     t.string  "owner_type"
   end
@@ -495,10 +690,15 @@     t.integer "profile_id"
   end
 
   create_table "licenses", force: :cascade do |t|
-    t.string  "name",           null: false
-    t.string  "slug",           null: false
-    t.string  "url"
-    t.integer "environment_id", null: false
+    t.string  "name",           limit: 255, null: false
+    t.string  "slug",           limit: 255, null: false
+    t.string  "url",            limit: 255
+    t.integer "environment_id",             null: false
+  end
+
+  create_table "mail_schedules", force: :cascade do |t|
+    t.integer  "dest_count"
+    t.datetime "scheduled_to"
   end
 
   create_table "mailing_sents", force: :cascade do |t|
@@ -509,26 +709,55 @@     t.datetime "updated_at"
   end
 
   create_table "mailings", force: :cascade do |t|
-    t.string   "type"
-    t.string   "subject"
+    t.string   "type",        limit: 255
+    t.string   "subject",     limit: 255
     t.text     "body"
     t.integer  "source_id"
-    t.string   "source_type"
+    t.string   "source_type", limit: 255
     t.integer  "person_id"
-    t.string   "locale"
+    t.string   "locale",      limit: 255
     t.datetime "created_at"
     t.datetime "updated_at"
-    t.text     "data",        default: "--- {}\n"
+    t.text     "data"
+  end
+
+  create_table "mark_comment_as_read_plugin", force: :cascade do |t|
+    t.integer "comment_id"
+    t.integer "person_id"
+  end
+
+  add_index "mark_comment_as_read_plugin", ["comment_id", "person_id"], name: "index_mark_comment_as_read_plugin_on_comment_id_and_person_id", unique: true, using: :btree
+
+  create_table "mezuro_plugin_metrics", force: :cascade do |t|
+    t.string   "name",            limit: 255
+    t.float    "value"
+    t.integer  "metricable_id"
+    t.string   "metricable_type", limit: 255
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "mezuro_plugin_projects", force: :cascade do |t|
+    t.string   "name",             limit: 255
+    t.string   "identifier",       limit: 255
+    t.string   "personal_webpage", limit: 255
+    t.text     "description"
+    t.string   "repository_url",   limit: 255
+    t.string   "svn_error",        limit: 255
+    t.boolean  "with_tab"
+    t.integer  "profile_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
   end
 
   create_table "national_region_types", force: :cascade do |t|
-    t.string "name"
+    t.string "name", limit: 255
   end
 
   create_table "national_regions", force: :cascade do |t|
-    t.string   "name"
-    t.string   "national_region_code"
-    t.string   "parent_national_region_code"
+    t.string   "name",                        limit: 255
+    t.string   "national_region_code",        limit: 255
+    t.string   "parent_national_region_code", limit: 255
     t.datetime "created_at"
     t.datetime "updated_at"
     t.integer  "national_region_type_id"
@@ -537,6 +766,320 @@
   add_index "national_regions", ["name"], name: "name_index", using: :btree
   add_index "national_regions", ["national_region_code"], name: "code_index", using: :btree
 
+  create_table "oauth2_authorizations", force: :cascade do |t|
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "oauth2_resource_owner_type", limit: 255
+    t.integer  "oauth2_resource_owner_id"
+    t.integer  "client_id"
+    t.string   "scope",                      limit: 255
+    t.string   "code",                       limit: 40
+    t.string   "access_token_hash",          limit: 40
+    t.string   "refresh_token_hash",         limit: 40
+    t.datetime "expires_at"
+  end
+
+  add_index "oauth2_authorizations", ["access_token_hash"], name: "index_oauth2_authorizations_on_access_token_hash", unique: true, using: :btree
+  add_index "oauth2_authorizations", ["client_id", "code"], name: "index_oauth2_authorizations_on_client_id_and_code", unique: true, using: :btree
+  add_index "oauth2_authorizations", ["client_id", "oauth2_resource_owner_type", "oauth2_resource_owner_id"], name: "index_owner_client_pairs", unique: true, using: :btree
+  add_index "oauth2_authorizations", ["client_id", "refresh_token_hash"], name: "index_oauth2_authorizations_on_client_id_and_refresh_token_hash", unique: true, using: :btree
+
+  create_table "oauth2_clients", force: :cascade do |t|
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "oauth2_client_owner_type", limit: 255
+    t.integer  "oauth2_client_owner_id"
+    t.string   "name",                     limit: 255
+    t.string   "client_id",                limit: 255
+    t.string   "client_secret",            limit: 255
+    t.string   "redirect_uri",             limit: 255
+    t.integer  "image_id"
+    t.string   "site",                     limit: 255
+  end
+
+  add_index "oauth2_clients", ["client_id"], name: "index_oauth2_clients_on_client_id", unique: true, using: :btree
+  add_index "oauth2_clients", ["name"], name: "index_oauth2_clients_on_name", unique: true, using: :btree
+
+  create_table "oauth_access_grants", force: :cascade do |t|
+    t.integer  "resource_owner_id",             null: false
+    t.integer  "application_id",                null: false
+    t.string   "token",             limit: 255, null: false
+    t.integer  "expires_in",                    null: false
+    t.text     "redirect_uri",                  null: false
+    t.datetime "created_at",                    null: false
+    t.datetime "revoked_at"
+    t.string   "scopes",            limit: 255
+  end
+
+  add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
+
+  create_table "oauth_access_tokens", force: :cascade do |t|
+    t.integer  "resource_owner_id"
+    t.integer  "application_id"
+    t.string   "token",             limit: 255, null: false
+    t.string   "refresh_token",     limit: 255
+    t.integer  "expires_in"
+    t.datetime "revoked_at"
+    t.datetime "created_at",                    null: false
+    t.string   "scopes",            limit: 255
+  end
+
+  add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
+  add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree
+  add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
+
+  create_table "oauth_applications", force: :cascade do |t|
+    t.string   "name",         limit: 255, null: false
+    t.string   "uid",          limit: 255, null: false
+    t.string   "secret",       limit: 255, null: false
+    t.text     "redirect_uri",             null: false
+    t.datetime "created_at",               null: false
+    t.datetime "updated_at",               null: false
+  end
+
+  add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
+
+  create_table "oauth_client_plugin_auths", force: :cascade do |t|
+    t.integer  "provider_id"
+    t.boolean  "enabled"
+    t.datetime "created_at",                                        null: false
+    t.datetime "updated_at",                                        null: false
+    t.string   "type",             limit: 255
+    t.string   "provider_user_id", limit: 255
+    t.text     "access_token"
+    t.datetime "expires_at"
+    t.text     "scope"
+    t.text     "data",                         default: "--- {}\n"
+    t.integer  "profile_id"
+  end
+
+  add_index "oauth_client_plugin_auths", ["profile_id"], name: "index_oauth_client_plugin_auths_on_profile_id", using: :btree
+  add_index "oauth_client_plugin_auths", ["provider_id"], name: "index_oauth_client_plugin_auths_on_provider_id", using: :btree
+  add_index "oauth_client_plugin_auths", ["provider_user_id"], name: "index_oauth_client_plugin_auths_on_provider_user_id", using: :btree
+  add_index "oauth_client_plugin_auths", ["type"], name: "index_oauth_client_plugin_auths_on_type", using: :btree
+
+  create_table "oauth_client_plugin_providers", force: :cascade do |t|
+    t.integer  "environment_id"
+    t.string   "strategy",       limit: 255
+    t.string   "name",           limit: 255
+    t.text     "options"
+    t.boolean  "enabled"
+    t.integer  "image_id"
+    t.datetime "created_at",                 null: false
+    t.datetime "updated_at",                 null: false
+    t.text     "client_id"
+    t.text     "client_secret"
+  end
+
+  add_index "oauth_client_plugin_providers", ["client_id"], name: "index_oauth_client_plugin_providers_on_client_id", using: :btree
+
+  create_table "oauth_plugin_provider_auths", force: :cascade do |t|
+    t.string   "type",             limit: 255
+    t.integer  "profile_id"
+    t.integer  "provider_id"
+    t.string   "provider_user_id", limit: 255
+    t.text     "access_token"
+    t.datetime "expires_at"
+    t.text     "scope"
+    t.text     "data",                         default: "--- {}\n"
+    t.datetime "created_at",                                        null: false
+    t.datetime "updated_at",                                        null: false
+  end
+
+  add_index "oauth_plugin_provider_auths", ["profile_id", "provider_id"], name: "index_oauth_plugin_provider_auths_on_profile_id_and_provider_id", using: :btree
+  add_index "oauth_plugin_provider_auths", ["profile_id", "provider_user_id"], name: "oauth_index_profile_id_and_provider_user_id", using: :btree
+  add_index "oauth_plugin_provider_auths", ["profile_id"], name: "index_oauth_plugin_provider_auths_on_profile_id", using: :btree
+  add_index "oauth_plugin_provider_auths", ["provider_id"], name: "index_oauth_plugin_provider_auths_on_provider_id", using: :btree
+  add_index "oauth_plugin_provider_auths", ["provider_user_id"], name: "index_oauth_plugin_provider_auths_on_provider_user_id", using: :btree
+
+  create_table "oauth_plugin_providers", force: :cascade do |t|
+    t.integer  "environment_id"
+    t.string   "type",           limit: 255
+    t.string   "strategy",       limit: 255
+    t.string   "identifier",     limit: 255
+    t.string   "name",           limit: 255
+    t.string   "site",           limit: 255
+    t.integer  "image_id"
+    t.string   "key",            limit: 255
+    t.string   "secret",         limit: 255
+    t.text     "scope"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "oauth_plugin_providers", ["environment_id", "identifier"], name: "index_oauth_plugin_providers_on_environment_id_and_identifier", using: :btree
+  add_index "oauth_plugin_providers", ["environment_id"], name: "index_oauth_plugin_providers_on_environment_id", using: :btree
+  add_index "oauth_plugin_providers", ["identifier"], name: "index_oauth_plugin_providers_on_identifier", using: :btree
+  add_index "oauth_plugin_providers", ["strategy"], name: "index_oauth_plugin_providers_on_strategy", using: :btree
+  add_index "oauth_plugin_providers", ["type"], name: "index_oauth_plugin_providers_on_type", using: :btree
+
+  create_table "open_graph_plugin_tracks", force: :cascade do |t|
+    t.string   "type",             limit: 255
+    t.string   "context",          limit: 255
+    t.boolean  "enabled",                      default: true
+    t.integer  "tracker_id"
+    t.integer  "actor_id"
+    t.string   "action",           limit: 255
+    t.string   "object_type",      limit: 255
+    t.text     "object_data_url"
+    t.integer  "object_data_id"
+    t.string   "object_data_type", limit: 255
+    t.datetime "created_at",                                  null: false
+    t.datetime "updated_at",                                  null: false
+    t.datetime "published_at"
+    t.string   "story",            limit: 255
+  end
+
+  add_index "open_graph_plugin_tracks", ["action"], name: "index_open_graph_plugin_tracks_on_action", using: :btree
+  add_index "open_graph_plugin_tracks", ["actor_id"], name: "index_open_graph_plugin_tracks_on_actor_id", using: :btree
+  add_index "open_graph_plugin_tracks", ["context"], name: "index_open_graph_plugin_tracks_on_context", using: :btree
+  add_index "open_graph_plugin_tracks", ["enabled"], name: "index_open_graph_plugin_tracks_on_enabled", using: :btree
+  add_index "open_graph_plugin_tracks", ["object_data_id", "object_data_type"], name: "index_open_graph_plugin_tracks_object_data_id_type", using: :btree
+  add_index "open_graph_plugin_tracks", ["object_data_url"], name: "index_open_graph_plugin_tracks_on_object_data_url", using: :btree
+  add_index "open_graph_plugin_tracks", ["object_type"], name: "index_open_graph_plugin_tracks_on_object_type", using: :btree
+  add_index "open_graph_plugin_tracks", ["published_at"], name: "index_open_graph_plugin_tracks_on_published_at", using: :btree
+  add_index "open_graph_plugin_tracks", ["story"], name: "index_open_graph_plugin_tracks_on_story", using: :btree
+  add_index "open_graph_plugin_tracks", ["type", "context"], name: "index_open_graph_plugin_tracks_on_type_and_context", using: :btree
+  add_index "open_graph_plugin_tracks", ["type"], name: "index_open_graph_plugin_tracks_on_type", using: :btree
+
+  create_table "orders_cycle_plugin_cycle_orders", force: :cascade do |t|
+    t.integer  "cycle_id"
+    t.integer  "sale_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.integer  "purchase_id"
+  end
+
+  add_index "orders_cycle_plugin_cycle_orders", ["cycle_id", "sale_id"], name: "index_orders_cycle_plugin_cycle_orders_on_cycle_id_and_order_id", using: :btree
+  add_index "orders_cycle_plugin_cycle_orders", ["cycle_id", "sale_id"], name: "index_orders_cycle_plugin_cycle_orders_on_cycle_id_and_sale_id", using: :btree
+  add_index "orders_cycle_plugin_cycle_orders", ["cycle_id"], name: "index_orders_cycle_plugin_cycle_orders_on_cycle_id", using: :btree
+  add_index "orders_cycle_plugin_cycle_orders", ["purchase_id"], name: "index_orders_cycle_plugin_cycle_orders_on_purchase_id", using: :btree
+  add_index "orders_cycle_plugin_cycle_orders", ["sale_id"], name: "index_orders_cycle_plugin_cycle_orders_on_order_id", using: :btree
+  add_index "orders_cycle_plugin_cycle_orders", ["sale_id"], name: "index_orders_cycle_plugin_cycle_orders_on_sale_id", using: :btree
+
+  create_table "orders_cycle_plugin_cycle_products", force: :cascade do |t|
+    t.integer "cycle_id"
+    t.integer "product_id"
+  end
+
+  add_index "orders_cycle_plugin_cycle_products", ["cycle_id", "product_id"], name: "orders_cycle_plugin_index_PhBVTRFB", using: :btree
+  add_index "orders_cycle_plugin_cycle_products", ["cycle_id"], name: "orders_cycle_plugin_index_dqaEe7Hf", using: :btree
+  add_index "orders_cycle_plugin_cycle_products", ["product_id"], name: "orders_cycle_plugin_index_f5DmQ6w5Y", using: :btree
+
+  create_table "orders_cycle_plugin_cycles", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.string   "name",              limit: 255
+    t.text     "description"
+    t.datetime "start"
+    t.datetime "finish"
+    t.datetime "delivery_start"
+    t.datetime "delivery_finish"
+    t.decimal  "margin_percentage"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "status",            limit: 255
+    t.integer  "code"
+    t.text     "opening_message"
+    t.text     "data",                          default: "--- {}\n\n"
+  end
+
+  add_index "orders_cycle_plugin_cycles", ["code"], name: "index_orders_cycle_plugin_cycles_on_code", using: :btree
+  add_index "orders_cycle_plugin_cycles", ["profile_id"], name: "index_distribution_plugin_sessions_on_node_id", using: :btree
+  add_index "orders_cycle_plugin_cycles", ["status"], name: "index_distribution_plugin_sessions_on_status", using: :btree
+
+  create_table "orders_plugin_items", force: :cascade do |t|
+    t.integer  "product_id"
+    t.integer  "order_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.text     "data",                                    default: "--- {}\n\n"
+    t.string   "name",                        limit: 255
+    t.decimal  "price"
+    t.boolean  "draft"
+    t.decimal  "quantity_consumer_ordered"
+    t.decimal  "quantity_supplier_accepted"
+    t.decimal  "quantity_supplier_separated"
+    t.decimal  "quantity_supplier_delivered"
+    t.decimal  "quantity_consumer_received"
+    t.decimal  "price_consumer_ordered"
+    t.decimal  "price_supplier_accepted"
+    t.decimal  "price_supplier_separated"
+    t.decimal  "price_supplier_delivered"
+    t.decimal  "price_consumer_received"
+    t.integer  "unit_id_consumer_ordered"
+    t.integer  "unit_id_supplier_accepted"
+    t.integer  "unit_id_supplier_separated"
+    t.integer  "unit_id_supplier_delivered"
+    t.integer  "unit_id_consumer_received"
+    t.string   "type",                        limit: 255
+    t.string   "status",                      limit: 255
+  end
+
+  add_index "orders_plugin_items", ["order_id"], name: "index_distribution_plugin_ordered_products_on_order_id", using: :btree
+  add_index "orders_plugin_items", ["product_id"], name: "distribution_plugin_ordered_products_spid", using: :btree
+
+  create_table "orders_plugin_orders", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.integer  "consumer_id"
+    t.integer  "supplier_delivery_id"
+    t.integer  "consumer_delivery_id"
+    t.string   "status",                 limit: 255
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.integer  "code"
+    t.text     "profile_data",                       default: "--- {}\n\n"
+    t.text     "consumer_data",                      default: "--- {}\n\n"
+    t.text     "supplier_delivery_data",             default: "--- {}\n\n"
+    t.text     "consumer_delivery_data",             default: "--- {}\n\n"
+    t.text     "payment_data",                       default: "--- {}\n\n"
+    t.text     "data",                               default: "--- {}\n\n"
+    t.datetime "ordered_at"
+    t.datetime "accepted_at"
+    t.datetime "separated_at"
+    t.datetime "delivered_at"
+    t.datetime "received_at"
+    t.string   "source",                 limit: 255
+    t.string   "session_id",             limit: 255
+    t.boolean  "building_next_status"
+  end
+
+  add_index "orders_plugin_orders", ["consumer_delivery_id"], name: "index_distribution_plugin_orders_on_consumer_delivery_id", using: :btree
+  add_index "orders_plugin_orders", ["consumer_id"], name: "index_distribution_plugin_orders_on_consumer_id", using: :btree
+  add_index "orders_plugin_orders", ["profile_id"], name: "index_distribution_plugin_orders_on_session_id", using: :btree
+  add_index "orders_plugin_orders", ["session_id"], name: "index_orders_plugin_orders_on_session_id", using: :btree
+  add_index "orders_plugin_orders", ["status"], name: "index_distribution_plugin_orders_on_status", using: :btree
+  add_index "orders_plugin_orders", ["supplier_delivery_id"], name: "index_distribution_plugin_orders_on_supplier_delivery_id", using: :btree
+
+  create_table "payments_plugin_payment_methods", force: :cascade do |t|
+    t.string "slug"
+    t.string "name"
+    t.text   "description", default: ""
+  end
+
+  create_table "payments_plugin_payment_methods_profiles", force: :cascade do |t|
+    t.integer "profile_id"
+    t.integer "payment_method_id"
+  end
+
+  add_index "payments_plugin_payment_methods_profiles", ["profile_id"], name: "index_payments_plugin_payment_methods_profiles_on_profile_id", using: :btree
+
+  create_table "payments_plugin_payments", force: :cascade do |t|
+    t.integer  "orders_plugin_order_id"
+    t.integer  "profile_id"
+    t.integer  "payment_method_id"
+    t.integer  "operator_id"
+    t.decimal  "value"
+    t.text     "description"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "payments_plugin_payments", ["operator_id"], name: "index_payments_on_operator_id", using: :btree
+  add_index "payments_plugin_payments", ["orders_plugin_order_id"], name: "index_payments_plugin_payments_on_orders_plugin_order_id", using: :btree
+  add_index "payments_plugin_payments", ["payment_method_id"], name: "index_payment_methods_profiles_on_payment_method_id", using: :btree
+  add_index "payments_plugin_payments", ["payment_method_id"], name: "index_payments_on_payment_method_id", using: :btree
+  add_index "payments_plugin_payments", ["profile_id"], name: "index_payments_plugin_payments_on_profile_id", using: :btree
+
   create_table "price_details", force: :cascade do |t|
     t.decimal  "price",              default: 0.0
     t.integer  "product_id"
@@ -563,9 +1106,9 @@   add_index "product_qualifiers", ["product_id"], name: "index_product_qualifiers_on_product_id", using: :btree
   add_index "product_qualifiers", ["qualifier_id"], name: "index_product_qualifiers_on_qualifier_id", using: :btree
 
   create_table "production_costs", force: :cascade do |t|
-    t.string   "name"
+    t.string   "name",       limit: 255
     t.integer  "owner_id"
-    t.string   "owner_type"
+    t.string   "owner_type", limit: 255
     t.datetime "created_at"
     t.datetime "updated_at"
   end
@@ -573,31 +1116,33 @@
   create_table "products", force: :cascade do |t|
     t.integer  "profile_id"
     t.integer  "product_category_id"
-    t.string   "name"
+    t.string   "name",                limit: 255
     t.decimal  "price"
     t.text     "description"
     t.datetime "created_at"
     t.datetime "updated_at"
     t.decimal  "discount"
-    t.boolean  "available",           default: true
-    t.boolean  "highlighted",         default: false
+    t.boolean  "available",                       default: true
+    t.boolean  "highlighted",                     default: false
     t.integer  "unit_id"
     t.integer  "image_id"
-    t.string   "type"
+    t.string   "type",                limit: 255
     t.text     "data"
-    t.boolean  "archived",            default: false
+    t.boolean  "archived",                        default: false
+    t.float    "stored"
+    t.boolean  "use_stock",                       default: false
   end
 
   add_index "products", ["created_at"], name: "index_products_on_created_at", using: :btree
   add_index "products", ["product_category_id"], name: "index_products_on_product_category_id", using: :btree
-  add_index "products", ["profile_id"], name: "index_products_on_profile_id", using: :btree
+  add_index "products", ["profile_id"], name: "index_products_on_enterprise_id", using: :btree
 
   create_table "profile_activities", force: :cascade do |t|
     t.integer  "profile_id"
     t.integer  "activity_id"
-    t.string   "activity_type"
-    t.datetime "created_at",    null: false
-    t.datetime "updated_at",    null: false
+    t.string   "activity_type", limit: 255
+    t.datetime "created_at",                null: false
+    t.datetime "updated_at",                null: false
   end
 
   add_index "profile_activities", ["activity_id", "activity_type"], name: "index_profile_activities_on_activity_id_and_activity_type", using: :btree
@@ -607,12 +1152,12 @@
   create_table "profile_suggestions", force: :cascade do |t|
     t.integer  "person_id"
     t.integer  "suggestion_id"
-    t.string   "suggestion_type"
+    t.string   "suggestion_type", limit: 255
     t.text     "categories"
-    t.boolean  "enabled",         default: true
-    t.float    "score",           default: 0.0
-    t.datetime "created_at",                     null: false
-    t.datetime "updated_at",                     null: false
+    t.boolean  "enabled",                     default: true
+    t.float    "score",                       default: 0.0
+    t.datetime "created_at",                                 null: false
+    t.datetime "updated_at",                                 null: false
   end
 
   add_index "profile_suggestions", ["person_id"], name: "index_profile_suggestions_on_person_id", using: :btree
@@ -620,13 +1165,13 @@   add_index "profile_suggestions", ["score"], name: "index_profile_suggestions_on_score", using: :btree
   add_index "profile_suggestions", ["suggestion_id"], name: "index_profile_suggestions_on_suggestion_id", using: :btree
 
   create_table "profiles", force: :cascade do |t|
-    t.string   "name"
-    t.string   "type"
-    t.string   "identifier"
+    t.string   "name",                    limit: 255
+    t.string   "type",                    limit: 255
+    t.string   "identifier",              limit: 255
     t.integer  "environment_id"
-    t.boolean  "active",                             default: true
-    t.string   "address"
-    t.string   "contact_phone"
+    t.boolean  "active",                              default: true
+    t.string   "address",                 limit: 255
+    t.string   "contact_phone",           limit: 255
     t.integer  "home_page_id"
     t.integer  "user_id"
     t.integer  "region_id"
@@ -635,45 +1180,52 @@     t.datetime "created_at"
     t.float    "lat"
     t.float    "lng"
     t.integer  "geocode_precision"
-    t.boolean  "enabled",                            default: true
-    t.string   "nickname",                limit: 16
+    t.boolean  "enabled",                             default: true
+    t.string   "nickname",                limit: 255
     t.text     "custom_header"
     t.text     "custom_footer"
-    t.string   "theme"
-    t.boolean  "public_profile",                     default: true
+    t.string   "theme",                   limit: 255
+    t.boolean  "public_profile",                      default: true
     t.date     "birth_date"
     t.integer  "preferred_domain_id"
     t.datetime "updated_at"
-    t.boolean  "visible",                            default: true
+    t.boolean  "visible",                             default: true
     t.integer  "image_id"
-    t.boolean  "validated",                          default: true
-    t.string   "cnpj"
-    t.string   "national_region_code"
-    t.boolean  "is_template",                        default: false
+    t.integer  "bsc_id"
+    t.string   "company_name",            limit: 255
+    t.boolean  "validated",                           default: true
+    t.string   "cnpj",                    limit: 255
+    t.string   "national_region_code",    limit: 255
+    t.boolean  "is_template",                         default: false
     t.integer  "template_id"
-    t.string   "redirection_after_login"
-    t.integer  "friends_count",                      default: 0,          null: false
-    t.integer  "members_count",                      default: 0,          null: false
-    t.integer  "activities_count",                   default: 0,          null: false
-    t.string   "personal_website"
-    t.string   "jabber_id"
+    t.string   "redirection_after_login", limit: 255
+    t.integer  "friends_count",                       default: 0,          null: false
+    t.integer  "members_count",                       default: 0,          null: false
+    t.integer  "activities_count",                    default: 0,          null: false
+    t.string   "personal_website",        limit: 255
+    t.string   "jabber_id",               limit: 255
+    t.string   "usp_id",                  limit: 255
     t.integer  "welcome_page_id"
-    t.boolean  "allow_members_to_invite",            default: true
-    t.boolean  "invite_friends_only",                default: false
-    t.boolean  "secret",                             default: false
-    t.string   "editor",                             default: "tiny_mce", null: false
+    t.boolean  "allow_members_to_invite",             default: true
+    t.boolean  "invite_friends_only",                 default: false
+    t.boolean  "secret",                              default: false
+    t.string   "editor",                              default: "tiny_mce", null: false
     t.integer  "top_image_id"
   end
 
   add_index "profiles", ["activities_count"], name: "index_profiles_on_activities_count", using: :btree
   add_index "profiles", ["created_at"], name: "index_profiles_on_created_at", using: :btree
+  add_index "profiles", ["enabled"], name: "index_profiles_on_enabled", using: :btree
   add_index "profiles", ["environment_id"], name: "index_profiles_on_environment_id", using: :btree
   add_index "profiles", ["friends_count"], name: "index_profiles_on_friends_count", using: :btree
   add_index "profiles", ["identifier"], name: "index_profiles_on_identifier", using: :btree
   add_index "profiles", ["members_count"], name: "index_profiles_on_members_count", using: :btree
   add_index "profiles", ["region_id"], name: "index_profiles_on_region_id", using: :btree
+  add_index "profiles", ["type"], name: "index_profiles_on_type", using: :btree
   add_index "profiles", ["user_id", "type"], name: "index_profiles_on_user_id_and_type", using: :btree
   add_index "profiles", ["user_id"], name: "index_profiles_on_user_id", using: :btree
+  add_index "profiles", ["validated"], name: "index_profiles_on_validated", using: :btree
+  add_index "profiles", ["visible"], name: "index_profiles_on_visible", using: :btree
 
   create_table "profiles_circles", force: :cascade do |t|
     t.integer  "profile_id"
@@ -690,10 +1242,11 @@     t.integer "certifier_id"
   end
 
   create_table "qualifiers", force: :cascade do |t|
-    t.string   "name",           null: false
+    t.string   "name",           limit: 255, null: false
     t.integer  "environment_id"
     t.datetime "created_at"
     t.datetime "updated_at"
+    t.string   "uuid"
   end
 
   create_table "refused_join_community", id: false, force: :cascade do |t|
@@ -708,29 +1261,32 @@   end
 
   create_table "reported_images", force: :cascade do |t|
     t.integer "size"
-    t.string  "content_type"
-    t.string  "filename"
+    t.string  "content_type",    limit: 255
+    t.string  "filename",        limit: 255
     t.integer "height"
     t.integer "width"
     t.integer "abuse_report_id"
   end
 
   create_table "role_assignments", force: :cascade do |t|
-    t.integer  "accessor_id",   null: false
-    t.string   "accessor_type"
+    t.integer  "accessor_id",               null: false
+    t.string   "accessor_type", limit: 255
     t.integer  "resource_id"
-    t.string   "resource_type"
-    t.integer  "role_id",       null: false
+    t.string   "resource_type", limit: 255
+    t.integer  "role_id",                   null: false
     t.boolean  "is_global"
     t.datetime "created_at"
     t.datetime "updated_at"
   end
 
+  add_index "role_assignments", ["accessor_id", "accessor_type"], name: "index_role_assignments_on_accessor_id_and_accessor_type", using: :btree
+  add_index "role_assignments", ["resource_id", "resource_type"], name: "index_role_assignments_on_resource_id_and_resource_type", using: :btree
+
   create_table "roles", force: :cascade do |t|
-    t.string  "name"
-    t.string  "key"
-    t.boolean "system",         default: false
+    t.string  "name",           limit: 255
     t.text    "permissions"
+    t.string  "key",            limit: 255
+    t.boolean "system",                     default: false
     t.integer "environment_id"
     t.integer "profile_id"
   end
@@ -742,7 +1298,6 @@     t.integer  "receiver_id"
     t.integer  "scrap_id"
     t.datetime "created_at"
     t.datetime "updated_at"
-    t.integer  "context_id"
   end
 
   create_table "search_term_occurrences", force: :cascade do |t|
@@ -755,13 +1310,13 @@
   add_index "search_term_occurrences", ["created_at"], name: "index_search_term_occurrences_on_created_at", using: :btree
 
   create_table "search_terms", force: :cascade do |t|
-    t.string  "term"
+    t.string  "term",             limit: 255
     t.integer "context_id"
-    t.string  "context_type"
-    t.string  "asset",            default: "all"
-    t.float   "score",            default: 0.0
-    t.float   "relevance_score",  default: 0.0
-    t.float   "occurrence_score", default: 0.0
+    t.string  "context_type",     limit: 255
+    t.string  "asset",            limit: 255, default: "all"
+    t.float   "score",                        default: 0.0
+    t.float   "relevance_score",              default: 0.0
+    t.float   "occurrence_score",             default: 0.0
   end
 
   add_index "search_terms", ["asset"], name: "index_search_terms_on_asset", using: :btree
@@ -771,7 +1326,7 @@   add_index "search_terms", ["score"], name: "index_search_terms_on_score", using: :btree
   add_index "search_terms", ["term"], name: "index_search_terms_on_term", using: :btree
 
   create_table "sessions", force: :cascade do |t|
-    t.string   "session_id", null: false
+    t.string   "session_id", limit: 255, null: false
     t.text     "data"
     t.datetime "created_at"
     t.datetime "updated_at"
@@ -782,19 +1337,152 @@   add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
   add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
   add_index "sessions", ["user_id"], name: "index_sessions_on_user_id", using: :btree
 
+  create_table "shopping_cart_plugin_purchase_orders", force: :cascade do |t|
+    t.integer  "customer_id"
+    t.integer  "seller_id"
+    t.text     "data"
+    t.integer  "status"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "smssync_plugin_messages", force: :cascade do |t|
+    t.string   "uuid",            limit: 255
+    t.integer  "chat_message_id"
+    t.integer  "from_profile_id"
+    t.integer  "to_profile_id"
+    t.string   "from",            limit: 255
+    t.string   "sent_to",         limit: 255
+    t.string   "device_id",       limit: 255
+    t.text     "message"
+    t.datetime "sent_timestamp"
+    t.datetime "created_at",                  null: false
+    t.datetime "updated_at",                  null: false
+  end
+
+  create_table "sniffer_plugin_opportunities", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.integer  "opportunity_id"
+    t.string   "opportunity_type", limit: 255
+    t.datetime "created_at",                   null: false
+    t.datetime "updated_at",                   null: false
+  end
+
+  create_table "sniffer_plugin_profiles", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.boolean  "enabled"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+  end
+
+  create_table "stock_plugin_allocations", force: :cascade do |t|
+    t.integer  "place_id"
+    t.integer  "product_id"
+    t.decimal  "quantity"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.text     "description"
+  end
+
+  add_index "stock_plugin_allocations", ["place_id", "product_id"], name: "index_stock_plugin_allocations_on_place_id_and_product_id", using: :btree
+  add_index "stock_plugin_allocations", ["place_id"], name: "index_stock_plugin_allocations_on_place_id", using: :btree
+  add_index "stock_plugin_allocations", ["product_id"], name: "index_stock_plugin_allocations_on_product_id", using: :btree
+
+  create_table "stock_plugin_allocations_orders", force: :cascade do |t|
+    t.integer "order_id"
+    t.integer "stock_allocation_id"
+  end
+
+  create_table "stock_plugin_places", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.string   "name"
+    t.text     "description"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "stock_plugin_places", ["profile_id"], name: "index_stock_plugin_places_on_profile_id", using: :btree
+
+  create_table "sub_organizations_plugin_approve_paternity_relations", force: :cascade do |t|
+    t.integer "task_id"
+    t.integer "parent_id"
+    t.string  "parent_type", limit: 255
+    t.integer "child_id"
+    t.string  "child_type",  limit: 255
+  end
+
+  create_table "sub_organizations_plugin_relations", force: :cascade do |t|
+    t.integer "parent_id"
+    t.string  "parent_type", limit: 255
+    t.integer "child_id"
+    t.string  "child_type",  limit: 255
+  end
+
   create_table "suggestion_connections", force: :cascade do |t|
-    t.integer "suggestion_id",   null: false
-    t.integer "connection_id",   null: false
-    t.string  "connection_type", null: false
+    t.integer "suggestion_id",               null: false
+    t.integer "connection_id",               null: false
+    t.string  "connection_type", limit: 255, null: false
   end
 
+  create_table "suppliers_plugin_hubs", force: :cascade do |t|
+    t.string  "name"
+    t.string  "description"
+    t.integer "profile_id"
+  end
+
+  add_index "suppliers_plugin_hubs", ["profile_id"], name: "index_suppliers_plugin_hubs_on_profile_id", using: :btree
+
+  create_table "suppliers_plugin_source_products", force: :cascade do |t|
+    t.integer  "from_product_id"
+    t.integer  "to_product_id"
+    t.decimal  "quantity",        default: 1.0
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.integer  "supplier_id"
+  end
+
+  add_index "suppliers_plugin_source_products", ["from_product_id", "to_product_id"], name: "suppliers_plugin_index_dtBULzU3", using: :btree
+  add_index "suppliers_plugin_source_products", ["from_product_id"], name: "index_distribution_plugin_source_products_on_from_product_id", using: :btree
+  add_index "suppliers_plugin_source_products", ["supplier_id", "from_product_id", "to_product_id"], name: "suppliers_plugin_index_VBNqyeCP", using: :btree
+  add_index "suppliers_plugin_source_products", ["supplier_id", "from_product_id"], name: "suppliers_plugin_index_naHsVLS6cH", using: :btree
+  add_index "suppliers_plugin_source_products", ["supplier_id"], name: "suppliers_plugin_index_Lm5QPpV8", using: :btree
+  add_index "suppliers_plugin_source_products", ["to_product_id"], name: "index_distribution_plugin_source_products_on_to_product_id", using: :btree
+
+  create_table "suppliers_plugin_suppliers", force: :cascade do |t|
+    t.integer  "consumer_id"
+    t.string   "name",              limit: 255
+    t.string   "name_abbreviation", limit: 255
+    t.text     "description"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.integer  "profile_id"
+    t.boolean  "active",                        default: true
+    t.string   "qualifiers",        limit: 255
+    t.string   "tags",              limit: 255
+    t.string   "lat",               limit: 255
+    t.string   "lng",               limit: 255
+    t.string   "phone"
+    t.string   "cell_phone"
+    t.string   "email"
+    t.integer  "hub_id"
+    t.string   "address"
+    t.string   "city"
+    t.string   "state"
+    t.string   "zip"
+  end
+
+  add_index "suppliers_plugin_suppliers", ["consumer_id"], name: "index_distribution_plugin_suppliers_on_consumer_id", using: :btree
+  add_index "suppliers_plugin_suppliers", ["hub_id"], name: "index_suppliers_plugin_suppliers_on_hub_id", using: :btree
+  add_index "suppliers_plugin_suppliers", ["profile_id", "consumer_id"], name: "index_suppliers_plugin_suppliers_on_profile_id_and_consumer_id", using: :btree
+  add_index "suppliers_plugin_suppliers", ["profile_id"], name: "index_suppliers_plugin_suppliers_on_profile_id", using: :btree
+
   create_table "taggings", force: :cascade do |t|
     t.integer  "tag_id"
     t.integer  "taggable_id"
-    t.string   "taggable_type"
+    t.string   "taggable_type", limit: 255
     t.datetime "created_at"
     t.integer  "tagger_id"
-    t.string   "tagger_type"
+    t.string   "tagger_type",   limit: 255
     t.string   "context",       limit: 128
   end
 
@@ -803,10 +1491,10 @@   add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree
   add_index "taggings", ["taggable_id", "taggable_type"], name: "index_taggings_on_taggable_id_and_taggable_type", using: :btree
 
   create_table "tags", force: :cascade do |t|
-    t.string  "name"
+    t.string  "name",           limit: 255
     t.integer "parent_id"
-    t.boolean "pending",        default: false
-    t.integer "taggings_count", default: 0
+    t.boolean "pending",                    default: false
+    t.integer "taggings_count",             default: 0
   end
 
   add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
@@ -819,11 +1507,12 @@     t.datetime "end_date"
     t.integer  "requestor_id"
     t.integer  "target_id"
     t.string   "code",           limit: 40
-    t.string   "type"
+    t.string   "type",           limit: 255
     t.datetime "created_at"
-    t.string   "target_type"
+    t.string   "target_type",    limit: 255
     t.integer  "image_id"
-    t.boolean  "spam",                      default: false
+    t.integer  "bsc_id"
+    t.boolean  "spam",                       default: false
     t.integer  "responsible_id"
     t.integer  "closed_by_id"
   end
@@ -844,43 +1533,43 @@   add_index "terms_forum_people", ["forum_id", "person_id"], name: "index_terms_forum_people_on_forum_id_and_person_id", using: :btree
 
   create_table "thumbnails", force: :cascade do |t|
     t.integer "size"
-    t.string  "content_type"
-    t.string  "filename"
+    t.string  "content_type", limit: 255
+    t.string  "filename",     limit: 255
     t.integer "height"
     t.integer "width"
     t.integer "parent_id"
-    t.string  "thumbnail"
+    t.string  "thumbnail",    limit: 255
   end
 
   add_index "thumbnails", ["parent_id"], name: "index_thumbnails_on_parent_id", using: :btree
 
   create_table "units", force: :cascade do |t|
-    t.string  "singular",       null: false
-    t.string  "plural",         null: false
+    t.string  "singular",       limit: 255, null: false
+    t.string  "plural",         limit: 255, null: false
     t.integer "position"
-    t.integer "environment_id", null: false
+    t.integer "environment_id",             null: false
   end
 
   create_table "users", force: :cascade do |t|
-    t.string   "login"
-    t.string   "email"
+    t.string   "login",                      limit: 255
+    t.string   "email",                      limit: 255
     t.string   "crypted_password",           limit: 40
     t.string   "salt",                       limit: 40
     t.datetime "created_at"
     t.datetime "updated_at"
-    t.string   "remember_token"
+    t.string   "remember_token",             limit: 255
     t.datetime "remember_token_expires_at"
     t.text     "terms_of_use"
     t.string   "terms_accepted",             limit: 1
     t.integer  "environment_id"
-    t.string   "password_type"
-    t.boolean  "enable_email",                          default: false
-    t.string   "last_chat_status",                      default: ""
-    t.string   "chat_status",                           default: ""
+    t.string   "password_type",              limit: 255
+    t.boolean  "enable_email",                           default: false
+    t.string   "last_chat_status",           limit: 255, default: ""
+    t.string   "chat_status",                limit: 255, default: ""
     t.datetime "chat_status_at"
     t.string   "activation_code",            limit: 40
     t.datetime "activated_at"
-    t.string   "return_to"
+    t.string   "return_to",                  limit: 255
     t.datetime "last_login_at"
     t.string   "private_token"
     t.datetime "private_token_generated_at"
@@ -892,12 +1581,38 @@     t.text    "restrictions"
     t.integer "organization_id"
   end
 
+  create_table "volunteers_plugin_assignments", force: :cascade do |t|
+    t.integer  "profile_id"
+    t.integer  "period_id"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+  end
+
+  add_index "volunteers_plugin_assignments", ["period_id"], name: "index_volunteers_plugin_assignments_on_period_id", using: :btree
+  add_index "volunteers_plugin_assignments", ["profile_id", "period_id"], name: "index_volunteers_plugin_assignments_on_profile_id_and_period_id", using: :btree
+  add_index "volunteers_plugin_assignments", ["profile_id"], name: "index_volunteers_plugin_assignments_on_profile_id", using: :btree
+
+  create_table "volunteers_plugin_periods", force: :cascade do |t|
+    t.integer  "owner_id"
+    t.string   "owner_type",         limit: 255
+    t.text     "name"
+    t.datetime "start"
+    t.datetime "end"
+    t.integer  "minimum_assigments"
+    t.integer  "maximum_assigments"
+    t.datetime "created_at",                     null: false
+    t.datetime "updated_at",                     null: false
+  end
+
+  add_index "volunteers_plugin_periods", ["owner_id", "owner_type"], name: "index_volunteers_plugin_periods_on_owner_id_and_owner_type", using: :btree
+  add_index "volunteers_plugin_periods", ["owner_type"], name: "index_volunteers_plugin_periods_on_owner_type", using: :btree
+
   create_table "votes", force: :cascade do |t|
-    t.integer  "vote",          null: false
-    t.integer  "voteable_id",   null: false
-    t.string   "voteable_type", null: false
+    t.integer  "vote",                      null: false
+    t.integer  "voteable_id",               null: false
+    t.string   "voteable_type", limit: 255, null: false
     t.integer  "voter_id"
-    t.string   "voter_type"
+    t.string   "voter_type",    limit: 255
     t.datetime "created_at"
     t.datetime "updated_at"
   end
@@ -905,5 +1620,8 @@
   add_index "votes", ["voteable_id", "voteable_type"], name: "fk_voteables", using: :btree
   add_index "votes", ["voter_id", "voter_type"], name: "fk_voters", using: :btree
 
+  add_foreign_key "payments_plugin_payments", "orders_plugin_orders"
+  add_foreign_key "payments_plugin_payments", "profiles"
   add_foreign_key "profiles_circles", "circles", on_delete: :cascade
+  add_foreign_key "suppliers_plugin_hubs", "profiles"
 end




diff --git a/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb b/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb
index 63be8f09f2d4a70c61bede8f9bc7bf9778b3e463..63f3028bbfe1e49e007f460486b2a7f0fda6e9de 100644
--- a/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb
+++ b/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb
@@ -101,5 +101,6 @@     purchase.destroy if purchase.items(true).blank?
   end
 
   handle_asynchronously :add_purchases_items
+  handle_asynchronously :remove_purchases_items
 
 end




diff --git a/plugins/products/views/products_plugin/page/show.html.erb b/plugins/products/views/products_plugin/page/show.html.erb
index af6a69eb245da169329b6911ea3e6563570d65cc..fc144ad7ce2104e0d671f1b27e35bf6d7b5d5204 100644
--- a/plugins/products/views/products_plugin/page/show.html.erb
+++ b/plugins/products/views/products_plugin/page/show.html.erb
@@ -96,7 +96,7 @@ <%= button_bar do %>
   <%= button_to_function :back, _('Back to the product listing'), "catalog.product.back(#{params[:rank]})" %>
   <% if user and (@user_is_admin or user.is_admin? profile) %>
     <%= button :add, _('Add product or service'), controller: "products_plugin/page", action: :new, profile: profile.identifier %>
-    <%= button :delete, _('Remove product or service'), {:action => 'destroy', :id => @product}, :class => 'requires-permission-products_plugin/page', :confirm => _('Are you sure you want to remove this product?') %>
+    <%= button :delete, _('Remove product or service'), {action: :destroy, id: @product, profile: profile.identifier}, class: 'requires-permission-products_plugin/page', confirm: _('Are you sure you want to remove this product?') %>
   <% end %>
 <% end %>
 




diff --git a/plugins/suppliers/public/javascripts/views/consumer-box.tag.slim b/plugins/suppliers/public/javascripts/views/consumer-box.tag.slim
index 543c50c9f8a679bc15c4c47f6600eb172ee70693..7f9ec36fedb09ddd44b31883cfdb349f763ce162 100644
--- a/plugins/suppliers/public/javascripts/views/consumer-box.tag.slim
+++ b/plugins/suppliers/public/javascripts/views/consumer-box.tag.slim
@@ -19,7 +19,7 @@               |{t('views.consumer.index.active')}
             .state if="{!consumer.active}"
               |{t('views.consumer.index.inactive')}
       div.col-xs-3
-        button 
+        button
           |{t('views.consumer.index.detail')}
 
   javascript:




diff --git a/plugins/suppliers/public/javascripts/views/consumer-view.tag.slim b/plugins/suppliers/public/javascripts/views/consumer-view.tag.slim
index 9c10b5c03023b4f8df93016d91354a3d6092492b..096bef66dbe38f52983e4632a87c65e88f396e9c 100644
--- a/plugins/suppliers/public/javascripts/views/consumer-view.tag.slim
+++ b/plugins/suppliers/public/javascripts/views/consumer-view.tag.slim
@@ -13,9 +13,9 @@                 h1
                   |{consumer.name}
                   span if="{consumer.name != consumer.profile_name}"
                     |  ({consumer.profile_name})
-              a.cs-button href="" onclick='{remove}' 
+              a.cs-button href="" onclick='{remove}'
                 |{cs.t("views.consumer.index.remove")}
-              a.cs-button href="" onclick='{toggle}' if="{consumer.active}" 
+              a.cs-button href="" onclick='{toggle}' if="{consumer.active}"
                 |{cs.t("views.consumer.index.disable")}
               a.cs-button href="" onclick='{toggle}' if="{!consumer.active}"
                 |{cs.t("views.consumer.index.enable")}
@@ -143,6 +143,12 @@       this.consumerUrl = Routes.profile_path({profile: this.consumer.identifier})
       if (this.consumer.purchases == undefined)
         this.consumer.purchases = {}
       this.purchases = this.consumer.purchases
+      $(this.root).find('input,textarea').each(function (i,el) {
+        el.value = el.getAttribute('value')
+      })
+      $(this.root).find('select').each(function (i,el) {
+        $(el).val(this.consumer[$(el).attr("name")])
+      }.bind(this))
     }
     this.setConsumer(opts.consumer)
 
@@ -186,7 +192,7 @@         var self = this
         $.get(purchasesUrl, {}, function(purchases) {
           purchases.forEach(function(p) {
             self.consumer.purchases.push(p);
-          }) 
+          })
           self.update();
         }, 'json');
       }




diff --git a/plugins/suppliers/public/javascripts/views/product-modal.tag.slim b/plugins/suppliers/public/javascripts/views/product-modal.tag.slim
index 23661359a88a4fac7fc39773e89ec463b8fff69b..c2ff7a7d3cde63a06741174cfaa6bb021885ee97 100644
--- a/plugins/suppliers/public/javascripts/views/product-modal.tag.slim
+++ b/plugins/suppliers/public/javascripts/views/product-modal.tag.slim
@@ -14,7 +14,7 @@             h1.title if="{product.id}"
               |{product.name}
             h1.title if="{!product.id}"
               |{t('views.product.add_product')}
-  
+
       .modal-body
         .row
           .col-xs-12.col-md-5
@@ -31,7 +31,8 @@                 label for="p-name"
                   |{t("views.product.product_name")}
                 small.title if="{product.id}"
                   |{t("views.product.name_change_warning")}
-                input type="text" value="{product.name}" id="p-name"
+                input type="text" value="{product.name}" id="p-name" name='name'
+
                 small.supplier_product_name show="{product.supplier_product_name != product.name && product.supplier_product_name != undefined}"
                   strong
                     |{t("views.product.supplier_product_name")}
@@ -44,8 +45,8 @@
               .form-group
                 label for="p-description"
                   |{t("views.product.description")}
-                textarea value="{product.description}" id="p-description"
-                
+                textarea value="{product.description}" id="p-description" name='description'
+
               .form-group
                 label for="p-product_category_id"
                   |{t("views.product.category")}
@@ -107,7 +108,7 @@         a href="" onclick="{remove}" class="remove_product" if="{product.id}"
           |{t('views.product.remove')}
         span.warning if="{product.id}"
           |{t('views.product.remove_warning')}
-          
+
 
   javascript:
     this.t = window.products.t
@@ -117,6 +118,12 @@       this.parent.typeaheadCategoryInit($('#p-product_category_id'), this.setCategory)
       this.parent.typeaheadUnitInit($('#p-unit_id'), this.setUnit)
     })
 
+    updateFormValues() {
+      $(this.root).find('input,textarea').each(function (i,el) {
+        el.value = el.getAttribute('value')
+      })
+    }
+
     setCategory(e, item) {
       this.product.product_category_id             = item.id
       this.productItem.product.product_category_id = item.id
@@ -151,7 +158,7 @@       if (!this.product.id)
         keys.push('supplier_id')
 
       var self = this;
-      
+
       keys.forEach(function(key) {
         var input = self["p-"+key];
 
@@ -220,14 +227,14 @@     }
 
     validate() {
       var keys = ['name', "supplier_id",'product_category_id']
-      
+
       for (var i in keys) {
         var input = this["p-"+keys[i]]
 
         if (keys[i] == 'supplier_id' && this.product.id)
           continue;
         // to validate category need to see the id instead of the input
-        if (keys[i] == 'product_category_id' && !this.product.product_category_id)
+        if (keys[i] == 'product_category_id' && typeof(this.product.product_category_id) == "string")
           input.value = ""
         if (input.value.trim() == "" || input.value == "0") {
           alert(this.t('views.product.validation_error_'+keys[i]))
@@ -241,7 +248,7 @@
     saveImage() {
       var self = this
       var saveUrl = Routes.suppliers_plugin_product_path({profile: noosfero.profile, action: 'set_image/'+this.product.id})
-      
+
       data = new FormData();
       data.append('image_builder', $('#image')[0].files[0])
       var opts = {




diff --git a/plugins/suppliers/public/javascripts/views/product-page.tag.slim b/plugins/suppliers/public/javascripts/views/product-page.tag.slim
index 8c3f4bbbd3c98247e55f893e3a8f677d4c7fd967..928445c04965b1c7dca2682d4ac47ff603b0596b 100644
--- a/plugins/suppliers/public/javascripts/views/product-page.tag.slim
+++ b/plugins/suppliers/public/javascripts/views/product-page.tag.slim
@@ -251,8 +251,7 @@     completeEdition(product, productItem) {
       this.tags['product-modal'].product = product
       this.tags['product-modal'].productItem = productItem
       this.tags['product-modal'].update()
-      // riot is buggy!!
-      $("#p-description").val(this.tags['product-modal'].product.description)
+      this.tags['product-modal'].updateFormValues()
     }
 
     typeaheadCategoryInit (input, selected) {
@@ -286,6 +285,9 @@         { displayKey: 'name', source: source.ttAdapter() }
       )
 
       input.on('typeahead:selected', selected)
+    }
+
+    import() {
     }
 
     add() {




diff --git a/test/unit/mail_queuer_test.rb b/test/unit/mail_queuer_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ce486bf603da6ca5f55460147154e0c33fb15609
--- /dev/null
+++ b/test/unit/mail_queuer_test.rb
@@ -0,0 +1,142 @@
+ENV['MAIL_QUEUER'] = '1'
+require_relative "../test_helper"
+
+class MailQueuerTest < ActiveSupport::TestCase
+
+  def setup
+    MailSchedule.delete_all
+    Delayed::Job.delete_all
+
+    ENV['MAIL_QUEUER_LIMIT'] = '100'
+
+    MailSchedule.create dest_count: 0, scheduled_to: Time.now
+    ApplicationMailer.deliveries = []
+  end
+
+  class Mailer < ApplicationMailer
+    def test to:[], cc:[], bcc:[], from: Environment.default.noreply_email
+      mail to: to, cc: cc, bcc: bcc, from: from,
+        subject: "test", body: 'test'
+    end
+  end
+
+  should 'fit the available limit' do
+    to  = 80.times.map{ |i| "b#{i}@example.com" }
+    cc  = 10.times.map{ |i| "b#{i}@example.com" }
+    bcc =  9.times.map{ |i| "b#{i}@example.com" }
+    Mailer.test(to: to, cc: cc, bcc: bcc).deliver
+
+    Delayed::Worker.new.work_off
+    message = ApplicationMailer.deliveries.last
+    assert_equal 99, MailSchedule.first.dest_count
+    assert_equal to, message.to
+    assert_equal cc, message.cc
+    assert_equal bcc, message.bcc
+  end
+
+
+  should 'break the mail when :to is bigger than limit' do
+    to  = 100.times.map{ |i| "b#{i}@example.com" }
+    cc  = ["cc@example.com"]
+    bcc = ["bcc@example.com"]
+    Mailer.test(to: to, cc: cc, bcc: bcc).deliver
+
+    Delayed::Worker.new.work_off
+    assert_equal 1, ApplicationMailer.deliveries.count
+    message = ApplicationMailer.deliveries.first
+    assert_equal 99, MailSchedule.first.dest_count
+    assert_equal to+cc, message.reply_to
+    assert_equal to.first(99), message.to
+    assert message.cc.blank?
+    assert message.bcc.blank?
+
+    message = job_message
+    assert_equal 3, MailSchedule.last.dest_count
+    assert_equal to+cc, message.reply_to
+    assert_equal [to.last], message.to
+    assert_equal cc, message.cc
+    assert_equal bcc, message.bcc
+  end
+
+  should 'break the mail with cc is bigger than limit' do
+    to  = 10.times.map{ |i| "b#{i}@example.com" }
+    cc  = 100.times.map{ |i| "b#{i}@example.com" }
+    bcc = ["bcc@example.com"]
+    Mailer.test(to: to, cc: cc, bcc: bcc).deliver
+
+    Delayed::Worker.new.work_off
+    assert_equal 1, ApplicationMailer.deliveries.count
+    message = ApplicationMailer.deliveries.first
+    assert_equal 99, MailSchedule.first.dest_count
+    assert_equal to+cc, message.reply_to
+    assert_equal to, message.to
+    assert_equal cc.first(89), message.cc
+    assert message.bcc.blank?
+
+    message = job_message
+    assert_equal 13, MailSchedule.last.dest_count
+    assert_equal to+cc, message.reply_to
+    assert_equal [to.first], message.to
+    assert_equal cc[89..-1], message.cc
+    assert_equal bcc, message.bcc
+  end
+
+  should 'break the mail with bcc is bigger than limit' do
+    to  = 10.times.map{ |i| "b#{i}@example.com" }
+    cc  = 10.times.map{ |i| "b#{i}@example.com" }
+    bcc = 80.times.map{ |i| "b#{i}@example.com" }
+    Mailer.test(to: to, cc: cc, bcc: bcc).deliver
+
+    Delayed::Worker.new.work_off
+    assert_equal 1, ApplicationMailer.deliveries.count
+    message = ApplicationMailer.deliveries.first
+    assert_equal 99, MailSchedule.first.dest_count
+    assert_equal to+cc, message.reply_to
+    assert_equal to, message.to
+    assert_equal cc, message.cc
+    assert_equal bcc.first(79), message.bcc
+
+    message = job_message
+    assert_equal 2, MailSchedule.last.dest_count
+    assert_equal to+cc, message.reply_to
+    assert_equal [to.first], message.to
+    assert message.cc.blank?
+    assert_equal [bcc.last], message.bcc
+  end
+
+  should 'send in the next hour if available_limit < dest_count < limit' do
+    MailSchedule.last.update dest_count: 90
+
+    to  = 10.times.map{ |i| "b#{i}@example.com" }
+    cc  = 10.times.map{ |i| "b#{i}@example.com" }
+    bcc =  9.times.map{ |i| "b#{i}@example.com" }
+    Mailer.test(to: to, cc: cc, bcc: bcc).deliver
+
+    assert_equal 2, MailSchedule.count
+    assert_equal 90, MailSchedule.first.dest_count
+    assert_equal 29, MailSchedule.last.dest_count
+    assert_equal MailSchedule.last.scheduled_to, MailSchedule.first.scheduled_to + 1.hour
+
+    Delayed::Worker.new.work_off
+    assert_equal nil, ApplicationMailer.deliveries.last
+
+    message = job_message
+    assert_equal to, message.to
+    assert_equal cc, message.cc
+    assert_equal bcc, message.bcc
+  end
+
+  protected
+
+  def job_message job=Delayed::Job.last
+    y   = YAML.load job.handler
+    l   = y.job_data['arguments']
+    m   = l.first
+    bcc = l.second
+
+    msg = Mail.read_from_string m
+    msg.bcc = bcc
+    msg
+  end
+
+end