cirandas.net

commit 0393b8714b38b6b959bc3233d45d214b97bfea3b

Author: Braulio Bhavamitra <braulio@prout.io>

Merge branch 'master' of http://github.com/CIRANDAS/noosfero-ecosol into stores

%!v(PANIC=String method: strings: negative Repeat count)


diff --git a/Gemfile.lock b/Gemfile.lock
index e81cc904f40743b40a09879d65be1c6331d573d4..ecfde0a40d9c2c9cc4934ea7a3040887fe8a842e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -164,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.6.0)
+    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)
@@ -181,6 +182,10 @@     babel-source (5.8.35)
     babel-transpiler (0.7.0)
       babel-source (>= 4.0, < 6)
       execjs (~> 2.0)
+    better_errors (2.1.1)
+      coderay (>= 1.0.0)
+      erubis (>= 2.6.6)
+      rack (>= 0.9.0)
     binding_of_caller (0.7.2)
       debug_inspector (>= 0.0.1)
     browser (2.4.0)
@@ -218,10 +223,10 @@     daemons (1.2.4)
     dalli (2.7.6)
     database_cleaner (1.6.1)
     debug_inspector (0.0.3)
-    delayed_job (4.1.2)
-      activesupport (>= 3.0, < 5.1)
-    delayed_job_active_record (4.1.1)
-      activerecord (>= 3.0, < 5.1)
+    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)
@@ -239,8 +244,22 @@     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.4)
@@ -284,6 +303,7 @@       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)
@@ -292,6 +312,12 @@     js-routes (1.2.6)
       railties (>= 3.2)
       sprockets-rails
     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)
@@ -325,13 +351,45 @@       metaclass (~> 0.0.1)
     multi_json (1.12.1)
     multi_test (0.1.2)
     multi_xml (0.6.0)
+    multipart-post (2.0.0)
     mustermann (1.0.0)
     mustermann-grape (1.0.0)
       mustermann (~> 1.0.0)
     netrc (0.11.0)
-    newrelic_rpm (4.1.0.333)
-    nokogiri (1.7.2)
+    newrelic_rpm (4.2.0.334)
+    nokogiri (1.6.8.1)
       mini_portile2 (~> 2.1.0)
+    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.3.0)
+      omniauth (~> 1.5)
+      omniauth-oauth2 (>= 1.4.0, < 2.0)
+    omniauth-google-oauth2 (0.4.1)
+      jwt (~> 1.5.2)
+      multi_json (~> 1.3)
+      omniauth (>= 1.1.1)
+      omniauth-oauth2 (>= 1.3.1)
+    omniauth-oauth (1.1.0)
+      oauth
+      omniauth (~> 1.0)
+    omniauth-oauth2 (1.4.0)
+      oauth2 (~> 1.0)
+      omniauth (~> 1.2)
+    omniauth-twitter (1.4.0)
+      omniauth-oauth (~> 1.1)
+      rack
     pg (0.20.0)
     pothoven-attachment_fu (3.2.18)
     power_assert (1.0.2)
@@ -348,8 +406,6 @@     pry (0.10.4)
       coderay (~> 1.1.0)
       method_source (~> 0.8.1)
       slop (~> 3.4)
-    pry-rails (0.3.6)
-      pry (>= 0.10.4)
     public_suffix (2.0.5)
     puma (3.8.2)
     puma_worker_killer (0.1.0)
@@ -362,6 +418,12 @@     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)
@@ -395,6 +457,7 @@       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)
@@ -466,7 +529,7 @@     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)
@@ -481,7 +544,7 @@       activesupport (>= 3.0)
       sprockets (>= 2.8, < 4.0)
     stackprof (0.2.10)
     temple (0.8.0)
-    test-unit (3.2.3)
+    test-unit (3.2.4)
       power_assert
     text (1.3.1)
     therubyracer (0.12.3)
@@ -505,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)
@@ -518,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
@@ -542,6 +606,7 @@   acts_as_versioned (> 0.0.0)!
   api-pagination (>= 4.1.1)
   assets_live_compile (>= 0.2.1)
   axlsx
+  better_errors
   binding_of_caller
   browser
   capybara (~> 2.2)
@@ -560,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
@@ -575,6 +643,7 @@   html2haml
   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)
@@ -586,13 +655,20 @@   minitest-reporters
   mocha (~> 1.1.0)
   monkey_patches (= 0.0.0)!
   newrelic_rpm
-  nokogiri (~> 1.7.0)
+  nokogiri (~> 1.6.0)
+  oj (~> 2.0)
+  oj_mimic_json
+  omniauth
+  omniauth-facebook
+  omniauth-github
+  omniauth-google-oauth2
+  omniauth-oauth2
+  omniauth-twitter
   pg
   pothoven-attachment_fu (~> 3.2.16)
   premailer-rails
   protected_attributes
   pry
-  pry-rails
   puma_worker_killer
   rack-contrib
   rack-cors
@@ -602,6 +678,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)
@@ -636,4 +713,4 @@   wirble
   xss_terminate (= 0.0.0)!
 
 BUNDLED WITH
-   1.14.6
+   1.13.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..fd706bce55f785908b2827a79639913e27f36aae
--- /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 = to.dup
+      orig_cc = cc.dup
+      dests   = {
+        to:  self.to,
+        cc:  self.cc,
+        bcc: 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
+        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/app/views/content_viewer/view_page.html.erb b/app/views/content_viewer/view_page.html.erb
index 72ce525e7e858923d914f22c692bf2f5b0b7e7da..97924343e375d3a68627555f28d489e4572ac1c1 100644
--- a/app/views/content_viewer/view_page.html.erb
+++ b/app/views/content_viewer/view_page.html.erb
@@ -31,12 +31,6 @@
 <% cache_if @page.cacheable?, @page.cache_key(params, user, language) do %>
   <div class="<%="article-body article-body-" + @page.css_class_name %>">
     <% options = @page.image? ? {:gallery_view => true} : {} %>
-    <% if @page.image.present? && !@page.event? && !@page.blog? %>
-      <div class="article-body-img">
-        <%= image_tag(@page.image.public_filename) %>
-        <p><%= @page.image.label%></p>
-      </div>
-    <% end %>
     <%= article_to_html(@page, options) %>
     <br style="clear:both" />
   </div> <!-- end class="article-body" -->




diff --git a/config/Gemfile b/config/Gemfile
index 0daad1c61fb5a61d180e88cbcf96b9ed0941f596..891f4b7ca1129e5ff2573d80fb9d2337a431dcf0 100644
--- a/config/Gemfile
+++ b/config/Gemfile
@@ -47,9 +47,10 @@
 platform :ruby do
   gem 'unicode'
   group :performance do
+
     # FIXME: stack level too deep
-    #gem 'oj'
-    #gem 'oj_mimic_json'
+    gem 'oj', '~> 2.0'
+    gem 'oj_mimic_json'
 
     gem 'fast_blank'
     gem 'gctools' if RUBY_VERSION >= '2.1.0' and RUBY_VERSION < '2.2.0'




diff --git a/config/application.rb b/config/application.rb
index 96a6164f4264845c7e2aa4eb2c574f63f2569d14..da1943588b95a575e76e5a5c20574f568c2e57b9 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -84,6 +84,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 1dffd414cf9808170f605eb8edfbd669ba82f8d8..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: 20170505164823) 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,50 +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.jsonb    "metadata",             default: {}
+    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", ["metadata"], name: "index_articles_on_metadata", using: :gin
-  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
@@ -198,56 +195,91 @@   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.jsonb    "metadata",        default: {}
+    t.string   "subtitle",                    default: ""
   end
 
   add_index "blocks", ["box_id"], name: "index_blocks_on_box_id", using: :btree
   add_index "blocks", ["enabled"], name: "index_blocks_on_enabled", using: :btree
   add_index "blocks", ["fetched_at"], name: "index_blocks_on_fetched_at", using: :btree
-  add_index "blocks", ["metadata"], name: "index_blocks_on_metadata", using: :gin
   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  "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.string  "display_color",        limit: 6
-    t.text    "ancestry"
-    t.boolean "visible_for_articles",           default: true
-    t.boolean "visible_for_profiles",           default: true
-    t.boolean "choosable",                      default: true
+    t.string  "uuid"
   end
 
   add_index "categories", ["parent_id"], name: "index_categories_on_parent_id", using: :btree
@@ -262,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
@@ -290,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
 
@@ -313,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
@@ -348,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
@@ -389,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
@@ -442,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
@@ -455,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
@@ -499,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|
@@ -513,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"
+  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"
-    t.text     "data",        default: "--- {}\n"
   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"
@@ -541,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"
@@ -567,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
@@ -577,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
@@ -611,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
@@ -624,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"
@@ -639,47 +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"
-    t.jsonb    "metadata",                           default: {}
   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", ["metadata"], name: "index_profiles_on_metadata", using: :gin
   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"
@@ -696,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|
@@ -714,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
@@ -748,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|
@@ -761,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
@@ -777,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"
@@ -788,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
 
@@ -809,12 +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.integer  "parent_id"
-    t.boolean  "pending",        default: false
-    t.integer  "taggings_count", default: 0
-    t.datetime "created_at"
-    t.datetime "updated_at"
+    t.string  "name",           limit: 255
+    t.integer "parent_id"
+    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
@@ -827,17 +1507,16 @@     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"
-    t.jsonb    "metadata",                  default: {}
   end
 
-  add_index "tasks", ["metadata"], name: "index_tasks_on_metadata", using: :gin
   add_index "tasks", ["requestor_id"], name: "index_tasks_on_requestor_id", using: :btree
   add_index "tasks", ["spam"], name: "index_tasks_on_spam", using: :btree
   add_index "tasks", ["status"], name: "index_tasks_on_status", using: :btree
@@ -854,50 +1533,47 @@   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"
-    t.jsonb    "metadata",                              default: {}
   end
-
-  add_index "users", ["metadata"], name: "index_users_on_metadata", using: :gin
 
   create_table "validation_infos", force: :cascade do |t|
     t.text    "validation_methodology"
@@ -905,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
@@ -918,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/locales/en-US.yml b/plugins/orders/locales/en-US.yml
index 469442f8144f09a8bb0b0a8e4e2aa13af76f6bba..8b921add5b8afd5abd48b008833847c93a8a3251 100644
--- a/plugins/orders/locales/en-US.yml
+++ b/plugins/orders/locales/en-US.yml
@@ -193,7 +193,7 @@
       item:
         no_stock: "This product is not stock anymore"
         _edit:
-          remove_from_order: "remove from order"
+          remove_from_order: "Remove"
           removed: 'removed'
           submit: 'OK'
           this_product_requires: "This product requires a minimum of %{value}. The minimum was kept."




diff --git a/plugins/orders/locales/pt-BR.yml b/plugins/orders/locales/pt-BR.yml
index f92be74d8bea065f5adb2c3921233fc757ad6f26..242f62d4923ce88f9a4c546b15c8d25556156dc5 100644
--- a/plugins/orders/locales/pt-BR.yml
+++ b/plugins/orders/locales/pt-BR.yml
@@ -194,7 +194,7 @@
       item:
         no_stock: "Este produto não está mais em estoque"
         _edit:
-          remove_from_order: "Remover do pedido"
+          remove_from_order: "Remover"
           removed: 'removido'
           submit: 'OK'
           this_product_requires: "Este produto requer um mínimo de %{value}. O mínimo foi mantido."




diff --git a/plugins/orders/models/orders_plugin/sale.rb b/plugins/orders/models/orders_plugin/sale.rb
index f01cbf64ae258009220b04b89c508f1ff0d58757..980e683c534931ebe7c8aa9e1596bb7af4d3b2d7 100644
--- a/plugins/orders/models/orders_plugin/sale.rb
+++ b/plugins/orders/models/orders_plugin/sale.rb
@@ -43,11 +43,11 @@     # ignore when status is being rewinded
     return if (Statuses.index(self.status) <= Statuses.index(self.status_was) rescue false)
 
     if self.status == 'ordered' and not [nil, 'ordered'].include? self.status_was
-      OrdersPlugin::Mailer.sale_confirmation(self).deliver
+      OrdersPlugin::Mailer.sale_confirmation(self).deliver_later
     elsif self.status == 'cancelled' and self.status_was != 'cancelled'
-      OrdersPlugin::Mailer.sale_cancellation(self).deliver
+      OrdersPlugin::Mailer.sale_cancellation(self).deliver_later
     elsif self.status == 'received' and self.status_was != 'received'
-      OrdersPlugin::Mailer.sale_received(self).deliver
+      OrdersPlugin::Mailer.sale_received(self).deliver_later
     end
   end
 end




diff --git a/plugins/orders/public/javascripts/views/item.tag.slim b/plugins/orders/public/javascripts/views/item.tag.slim
index 70fe3b4307e5c49e96089f9c90024011f81deebb..2454ef409eaac97de473424ee8638bb61c2e79f9 100644
--- a/plugins/orders/public/javascripts/views/item.tag.slim
+++ b/plugins/orders/public/javascripts/views/item.tag.slim
@@ -17,9 +17,9 @@         order-item-quantity-price each='{status_id,status in item.statuses}' item='{item}' status='{status}' status-id='{status_id}' if='{!(status.flags.not_modified && !status.flags.editable)}'
 
     .more
       .actions if='{parent.order.may_edit}'
-        a href='#' onclick='{adminRemove}' if='{parent.order.admin}'
+        a class="action-button" href='#' onclick='{adminRemove}' if='{parent.order.admin}'
           '{t('views.item._edit.remove_from_order')}
-        a href='#' onclick='{userRemove}' if='{!parent.order.admin}'
+        a class="action-button" href='#' onclick='{userRemove}' if='{!parent.order.admin}'
           '{t('views.item._edit.remove_from_order')}
 
       .orders-price-with-unit.price-with-unit.box-field if='{parent.order.may_edit}' title="{priceUnit()}"




diff --git a/plugins/orders/views/orders_plugin/shared/daterangepicker/_init.html.slim b/plugins/orders/views/orders_plugin/shared/daterangepicker/_init.html.slim
index dbedab3b6c88df55fd6b446dbe6fc5d78889316f..fc78af36f496e5959890d945b1468c7d2d97d8af 100644
--- a/plugins/orders/views/orders_plugin/shared/daterangepicker/_init.html.slim
+++ b/plugins/orders/views/orders_plugin/shared/daterangepicker/_init.html.slim
@@ -6,7 +6,7 @@   = javascript_include_tag '/assets/plugins/orders/javascripts/moment-with-locales.js'
   = javascript_include_tag '/assets/plugins/orders/javascripts/daterangepicker.js'
 
 javascript:
-  moment.locale(#{I18n.locale.downcase.to_json})
+  moment.locale("#{I18n.locale.downcase.to_s}")
 
   orders.daterangepicker.defaultOptions = {
     autoApply:           true,




diff --git a/plugins/orders_cycle/models/orders_cycle_plugin/item.rb b/plugins/orders_cycle/models/orders_cycle_plugin/item.rb
index 3b261bdcd7e3330c8e3653fb56247ee32e15c778..0473abe37149230cabc7d11b0896e1c2aeeba7d1 100644
--- a/plugins/orders_cycle/models/orders_cycle_plugin/item.rb
+++ b/plugins/orders_cycle/models/orders_cycle_plugin/item.rb
@@ -24,7 +24,7 @@   has_many :suppliers, through: :offered_product
   has_one :supplier, through: :offered_product
 
   after_save :update_order
-  after_save :change_purchases, if: :cycle
+  after_save :change_purchase, if: :cycle
   before_destroy :remove_purchase_item, if: :cycle
 
   def cycle
@@ -54,8 +54,10 @@   end
 
   protected
 
-  def change_purchases
-    return unless ["orders", 'purchases'].include? self.cycle.status
+  def change_purchase
+    # if we've already passed through purchases, don't change purchases
+    return unless self.cycle.status == 'orders'
+    # when it's draft, it handled by sale#change_purchases
     return if self.order.status == 'draft'
 
     if id_changed?




diff --git a/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb b/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb
index cbb03b1e0ee9dc77a6f39557ee9e6cc1f3519bc5..63be8f09f2d4a70c61bede8f9bc7bf9778b3e463 100644
--- a/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb
+++ b/plugins/orders_cycle/models/orders_cycle_plugin/sale.rb
@@ -25,8 +25,10 @@   end
 
   def change_purchases
     return unless self.status_was.present?
+    # only on sale confirmation
     if self.ordered_at_was.nil? and self.ordered_at.present?
       self.add_purchases_items
+    # only on sale cancellation/unconfirmation
     elsif self.ordered_at_was.present? and self.ordered_at.nil?
       self.remove_purchases_items
     end
@@ -60,7 +62,8 @@   def update_purchase_item item
     return unless supplier_product = item.product.supplier_product
     return unless supplier = supplier_product.profile
 
-    if item.quantity_supplier_accepted_was != item.quantity_supplier_accepted
+    previous_value = item.quantity_supplier_accepted_was || item.quantity_consumer_ordered
+    if previous_value != item.quantity_supplier_accepted
       qtt_diff = (item.quantity_supplier_accepted || 0) - (item.quantity_supplier_accepted_was || 0)
     elsif item.quantity_consumer_ordered_was != item.quantity_consumer_ordered
       qtt_diff = (item.quantity_consumer_ordered || 0) - (item.quantity_consumer_ordered_was || 0)




diff --git a/plugins/suppliers/public/javascripts/views/product-modal.tag.slim b/plugins/suppliers/public/javascripts/views/product-modal.tag.slim
index 73853576501c7b53af095a2386bf4ba071d02f3b..23661359a88a4fac7fc39773e89ec463b8fff69b 100644
--- a/plugins/suppliers/public/javascripts/views/product-modal.tag.slim
+++ b/plugins/suppliers/public/javascripts/views/product-modal.tag.slim
@@ -60,7 +60,7 @@
               .form-group
                 label for="p-supplier-price"
                   |{t("views.product.the_supplier_price")}
-                input type="text" value="{product.supplier_price}" id='p-supplier-price' oninput="{updatePrice}"
+                input type="number" value="{product.supplier_price}" id='p-supplier-price' oninput="{updatePrice}"
 
               .form-group
                 p.final_price
@@ -229,9 +229,7 @@           continue;
         // to validate category need to see the id instead of the input
         if (keys[i] == 'product_category_id' && !this.product.product_category_id)
           input.value = ""
-        console.log(input.value)
-        console.log(this.product.product_category_id)
-        if (input.value == "" || input.value == "0") {
+        if (input.value.trim() == "" || input.value == "0") {
           alert(this.t('views.product.validation_error_'+keys[i]))
           $("product-modal").scrollTo(100,1000)
           return false




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