yeshoua_crm 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/Rakefile +11 -0
 - data/lib/yeshoua_crm.rb +87 -0
 - data/lib/yeshoua_crm/acts_as_draftable/draft.rb +40 -0
 - data/lib/yeshoua_crm/acts_as_draftable/rcrm_acts_as_draftable.rb +154 -0
 - data/lib/yeshoua_crm/acts_as_list/list.rb +282 -0
 - data/lib/yeshoua_crm/acts_as_taggable/rcrm_acts_as_taggable.rb +350 -0
 - data/lib/yeshoua_crm/acts_as_taggable/tag.rb +81 -0
 - data/lib/yeshoua_crm/acts_as_taggable/tag_list.rb +111 -0
 - data/lib/yeshoua_crm/acts_as_taggable/tagging.rb +16 -0
 - data/lib/yeshoua_crm/acts_as_viewed/rcrm_acts_as_viewed.rb +274 -0
 - data/lib/yeshoua_crm/acts_as_votable/rcrm_acts_as_votable.rb +80 -0
 - data/lib/yeshoua_crm/acts_as_votable/rcrm_acts_as_voter.rb +20 -0
 - data/lib/yeshoua_crm/acts_as_votable/votable.rb +323 -0
 - data/lib/yeshoua_crm/acts_as_votable/vote.rb +28 -0
 - data/lib/yeshoua_crm/acts_as_votable/voter.rb +131 -0
 - data/lib/yeshoua_crm/assets_manager.rb +43 -0
 - data/lib/yeshoua_crm/currency.rb +439 -0
 - data/lib/yeshoua_crm/currency/formatting.rb +224 -0
 - data/lib/yeshoua_crm/currency/heuristics.rb +151 -0
 - data/lib/yeshoua_crm/currency/loader.rb +24 -0
 - data/lib/yeshoua_crm/helpers/external_assets_helper.rb +17 -0
 - data/lib/yeshoua_crm/helpers/form_tag_helper.rb +123 -0
 - data/lib/yeshoua_crm/helpers/tags_helper.rb +13 -0
 - data/lib/yeshoua_crm/helpers/vote_helper.rb +35 -0
 - data/lib/yeshoua_crm/liquid/drops/cells_drop.rb +86 -0
 - data/lib/yeshoua_crm/liquid/drops/issues_drop.rb +66 -0
 - data/lib/yeshoua_crm/liquid/drops/news_drop.rb +54 -0
 - data/lib/yeshoua_crm/liquid/drops/users_drop.rb +72 -0
 - data/lib/yeshoua_crm/liquid/filters/arrays.rb +177 -0
 - data/lib/yeshoua_crm/liquid/filters/base.rb +208 -0
 - data/lib/yeshoua_crm/money_helper.rb +65 -0
 - data/lib/yeshoua_crm/version.rb +3 -0
 - data/test/acts_as_draftable/draft_test.rb +29 -0
 - data/test/acts_as_draftable/rcrm_acts_as_draftable_test.rb +185 -0
 - data/test/acts_as_taggable/rcrm_acts_as_taggable_test.rb +345 -0
 - data/test/acts_as_taggable/tag_list_test.rb +34 -0
 - data/test/acts_as_taggable/tag_test.rb +72 -0
 - data/test/acts_as_taggable/tagging_test.rb +15 -0
 - data/test/acts_as_viewed/rcrm_acts_as_viewed_test.rb +47 -0
 - data/test/acts_as_votable/rcrm_acts_as_votable_test.rb +19 -0
 - data/test/acts_as_votable/rcrm_acts_as_voter_test.rb +14 -0
 - data/test/acts_as_votable/votable_test.rb +507 -0
 - data/test/acts_as_votable/voter_test.rb +296 -0
 - data/test/currency_test.rb +292 -0
 - data/test/liquid/drops/issues_drop_test.rb +34 -0
 - data/test/liquid/drops/news_drop_test.rb +38 -0
 - data/test/liquid/drops/projects_drop_test.rb +44 -0
 - data/test/liquid/drops/uses_drop_test.rb +36 -0
 - data/test/liquid/filters/arrays_filter_test.rb +24 -0
 - data/test/liquid/filters/base_filter_test.rb +63 -0
 - data/test/liquid/liquid_helper.rb +32 -0
 - data/test/models/issue.rb +14 -0
 - data/test/models/news.rb +3 -0
 - data/test/models/project.rb +8 -0
 - data/test/models/user.rb +11 -0
 - data/test/models/vote_classes.rb +33 -0
 - data/test/money_helper_test.rb +12 -0
 - data/test/schema.rb +121 -0
 - data/test/tags_helper_test.rb +29 -0
 - data/test/test_helper.rb +66 -0
 - data/test/vote_helper_test.rb +28 -0
 - data/yeshoua_crm.gemspec +28 -0
 - metadata +206 -0
 
| 
         @@ -0,0 +1,224 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            module YeshouaCrm
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Currency
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Formatting
         
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.included(base)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    [
         
     | 
| 
      
 7 
     | 
    
         
            +
                      [:thousands_separator, :delimiter, ","],
         
     | 
| 
      
 8 
     | 
    
         
            +
                      [:decimal_mark, :separator, "."]
         
     | 
| 
      
 9 
     | 
    
         
            +
                    ].each do |method, name, character|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      define_i18n_method(method, name, character)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def self.define_i18n_method(method, name, character)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    define_method(method) do
         
     | 
| 
      
 16 
     | 
    
         
            +
                      if self.class.use_i18n
         
     | 
| 
      
 17 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 18 
     | 
    
         
            +
                          I18n.t name, :scope => "number.currency.format", :raise => true
         
     | 
| 
      
 19 
     | 
    
         
            +
                        rescue I18n::MissingTranslationData
         
     | 
| 
      
 20 
     | 
    
         
            +
                          I18n.t name, :scope =>"number.format", :default => (currency.send(method) || character)
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
                      else
         
     | 
| 
      
 23 
     | 
    
         
            +
                        currency.send(method) || character
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                    alias_method name, method
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def format(value, currency, *rules)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    # support for old format parameters
         
     | 
| 
      
 31 
     | 
    
         
            +
                    rules = normalize_formatting_rules(rules)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    if currency
         
     | 
| 
      
 33 
     | 
    
         
            +
                      rules = self.localize_formatting_rules(rules, currency)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      rules = self.translate_formatting_rules(rules, currency.code) if rules[:translate]
         
     | 
| 
      
 35 
     | 
    
         
            +
                      rules[:decimal_mark] = currency.decimal_mark if rules[:decimal_mark].nil?
         
     | 
| 
      
 36 
     | 
    
         
            +
                      rules[:decimal_places] = currency.decimal_places
         
     | 
| 
      
 37 
     | 
    
         
            +
                      rules[:subunit_to_unit] = currency.subunit_to_unit
         
     | 
| 
      
 38 
     | 
    
         
            +
                      rules[:thousands_separator] = currency.thousands_separator if rules[:thousands_separator].nil?
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    rules = Currency.default_formatting_rules.merge(rules){|key, v1, v2| v2.nil? ? v1 : v2}
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    # if fractional == 0
         
     | 
| 
      
 43 
     | 
    
         
            +
                    if rules[:display_free].respond_to?(:to_str)
         
     | 
| 
      
 44 
     | 
    
         
            +
                      return rules[:display_free]
         
     | 
| 
      
 45 
     | 
    
         
            +
                    elsif rules[:display_free]
         
     | 
| 
      
 46 
     | 
    
         
            +
                      return "free"
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
                    # end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    symbol_value = currency.try(:symbol) || ""
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    formatted = value.abs.to_s
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    # if rules[:rounded_infinite_precision]
         
     | 
| 
      
 55 
     | 
    
         
            +
                    if currency
         
     | 
| 
      
 56 
     | 
    
         
            +
                      formatted.gsub!(/#{rules[:decimal_mark]}/, '.') unless '.' == rules[:decimal_mark]
         
     | 
| 
      
 57 
     | 
    
         
            +
                      formatted = ((BigDecimal(formatted) * currency.subunit_to_unit).round / BigDecimal(currency.subunit_to_unit.to_s)).to_s("F")
         
     | 
| 
      
 58 
     | 
    
         
            +
                      formatted.gsub!(/\..*/) do |decimal_part|
         
     | 
| 
      
 59 
     | 
    
         
            +
                        decimal_part << '0' while decimal_part.length < (currency.decimal_places + 1)
         
     | 
| 
      
 60 
     | 
    
         
            +
                        decimal_part
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
      
 62 
     | 
    
         
            +
                      formatted.gsub!(/\./, rules[:decimal_mark]) unless '.' == rules[:decimal_mark]
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    sign = value < 0 ? '-' : ''
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                    if rules[:no_cents] || (rules[:no_cents_if_whole] && cents % currency.subunit_to_unit == 0)
         
     | 
| 
      
 68 
     | 
    
         
            +
                      formatted = "#{formatted.to_i}"
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    # thousands_separator_value = currency.thousands_separator
         
     | 
| 
      
 72 
     | 
    
         
            +
                    # Determine thousands_separator
         
     | 
| 
      
 73 
     | 
    
         
            +
                    if rules.has_key?(:thousands_separator)
         
     | 
| 
      
 74 
     | 
    
         
            +
                      thousands_separator_value = rules[:thousands_separator] || ''
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
                    decimal_mark = rules[:decimal_mark]
         
     | 
| 
      
 77 
     | 
    
         
            +
                    # Apply thousands_separator
         
     | 
| 
      
 78 
     | 
    
         
            +
                    formatted.gsub!(regexp_format(formatted, rules, decimal_mark, symbol_value),
         
     | 
| 
      
 79 
     | 
    
         
            +
                                    "\\1#{thousands_separator_value}")
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    symbol_position = symbol_position_from(rules, currency) if currency
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                    if rules[:sign_positive] == true && (value >= 0)
         
     | 
| 
      
 84 
     | 
    
         
            +
                      sign = '+'
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                    if rules[:sign_before_symbol] == true
         
     | 
| 
      
 88 
     | 
    
         
            +
                      sign_before = sign
         
     | 
| 
      
 89 
     | 
    
         
            +
                      sign = ''
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                    if symbol_value && !symbol_value.empty?
         
     | 
| 
      
 93 
     | 
    
         
            +
                      symbol_value = "<span class=\"currency_symbol\">#{symbol_value}</span>" if rules[:html_wrap_symbol]
         
     | 
| 
      
 94 
     | 
    
         
            +
                      formatted = if symbol_position == :before
         
     | 
| 
      
 95 
     | 
    
         
            +
                        symbol_space = rules[:symbol_before_without_space] === false ? " " : ""
         
     | 
| 
      
 96 
     | 
    
         
            +
                        "#{sign_before}#{symbol_value}#{symbol_space}#{sign}#{formatted}"
         
     | 
| 
      
 97 
     | 
    
         
            +
                      else
         
     | 
| 
      
 98 
     | 
    
         
            +
                        symbol_space = rules[:symbol_after_without_space] ? "" : " "
         
     | 
| 
      
 99 
     | 
    
         
            +
                        "#{sign_before}#{sign}#{formatted}#{symbol_space}#{symbol_value}"
         
     | 
| 
      
 100 
     | 
    
         
            +
                      end
         
     | 
| 
      
 101 
     | 
    
         
            +
                    else
         
     | 
| 
      
 102 
     | 
    
         
            +
                      formatted="#{sign_before}#{sign}#{formatted}"
         
     | 
| 
      
 103 
     | 
    
         
            +
                    end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                    # apply_decimal_mark_from_rules(formatted, rules)
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                    if rules[:with_currency]
         
     | 
| 
      
 108 
     | 
    
         
            +
                      formatted << " "
         
     | 
| 
      
 109 
     | 
    
         
            +
                      formatted << '<span class="currency">' if rules[:html]
         
     | 
| 
      
 110 
     | 
    
         
            +
                      formatted << currency.to_s
         
     | 
| 
      
 111 
     | 
    
         
            +
                      formatted << '</span>' if rules[:html]
         
     | 
| 
      
 112 
     | 
    
         
            +
                    end
         
     | 
| 
      
 113 
     | 
    
         
            +
                    formatted
         
     | 
| 
      
 114 
     | 
    
         
            +
                  end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                  def default_formatting_rules
         
     | 
| 
      
 117 
     | 
    
         
            +
                    {
         
     | 
| 
      
 118 
     | 
    
         
            +
                      :decimal_mark =>".",
         
     | 
| 
      
 119 
     | 
    
         
            +
                      :thousands_separator => ",",
         
     | 
| 
      
 120 
     | 
    
         
            +
                      :subunit_to_unit => 100
         
     | 
| 
      
 121 
     | 
    
         
            +
                    }
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                  def regexp_format(formatted, rules, decimal_mark, symbol_value)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    regexp_decimal = Regexp.escape(decimal_mark)
         
     | 
| 
      
 126 
     | 
    
         
            +
                    if rules[:south_asian_number_formatting]
         
     | 
| 
      
 127 
     | 
    
         
            +
                      /(\d+?)(?=(\d\d)+(\d)(?:\.))/
         
     | 
| 
      
 128 
     | 
    
         
            +
                    else
         
     | 
| 
      
 129 
     | 
    
         
            +
                      # Symbols may contain decimal marks (E.g "դր.")
         
     | 
| 
      
 130 
     | 
    
         
            +
                      if formatted.sub(symbol_value.to_s, "") =~ /#{regexp_decimal}/
         
     | 
| 
      
 131 
     | 
    
         
            +
                        /(\d)(?=(?:\d{3})+(?:#{regexp_decimal}))/
         
     | 
| 
      
 132 
     | 
    
         
            +
                      else
         
     | 
| 
      
 133 
     | 
    
         
            +
                        /(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/
         
     | 
| 
      
 134 
     | 
    
         
            +
                      end
         
     | 
| 
      
 135 
     | 
    
         
            +
                    end
         
     | 
| 
      
 136 
     | 
    
         
            +
                  end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                  def translate_formatting_rules(rules, iso_code)
         
     | 
| 
      
 139 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 140 
     | 
    
         
            +
                      rules[:symbol] = I18n.t iso_code, :scope => "number.currency.symbol", :raise => true
         
     | 
| 
      
 141 
     | 
    
         
            +
                    rescue I18n::MissingTranslationData
         
     | 
| 
      
 142 
     | 
    
         
            +
                      # Do nothing
         
     | 
| 
      
 143 
     | 
    
         
            +
                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
                    rules
         
     | 
| 
      
 145 
     | 
    
         
            +
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                  def localize_formatting_rules(rules, currency)
         
     | 
| 
      
 148 
     | 
    
         
            +
                    if currency.iso_code == "JPY" && I18n.locale == :ja
         
     | 
| 
      
 149 
     | 
    
         
            +
                      rules[:symbol] = "円" unless rules[:symbol] == false
         
     | 
| 
      
 150 
     | 
    
         
            +
                      rules[:symbol_position] = :after
         
     | 
| 
      
 151 
     | 
    
         
            +
                      rules[:symbol_after_without_space] = true
         
     | 
| 
      
 152 
     | 
    
         
            +
                    elsif currency.iso_code == "CHF"
         
     | 
| 
      
 153 
     | 
    
         
            +
                      rules[:symbol_before_without_space] = false
         
     | 
| 
      
 154 
     | 
    
         
            +
                    end
         
     | 
| 
      
 155 
     | 
    
         
            +
                    rules
         
     | 
| 
      
 156 
     | 
    
         
            +
                  end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                  def symbol_value_from(rules)
         
     | 
| 
      
 159 
     | 
    
         
            +
                    if rules.has_key?(:symbol)
         
     | 
| 
      
 160 
     | 
    
         
            +
                      if rules[:symbol] === true
         
     | 
| 
      
 161 
     | 
    
         
            +
                        symbol
         
     | 
| 
      
 162 
     | 
    
         
            +
                      elsif rules[:symbol]
         
     | 
| 
      
 163 
     | 
    
         
            +
                        rules[:symbol]
         
     | 
| 
      
 164 
     | 
    
         
            +
                      else
         
     | 
| 
      
 165 
     | 
    
         
            +
                        ""
         
     | 
| 
      
 166 
     | 
    
         
            +
                      end
         
     | 
| 
      
 167 
     | 
    
         
            +
                    elsif rules[:html]
         
     | 
| 
      
 168 
     | 
    
         
            +
                      currency.html_entity == '' ? currency.symbol : currency.html_entity
         
     | 
| 
      
 169 
     | 
    
         
            +
                    elsif rules[:disambiguate] and currency.disambiguate_symbol
         
     | 
| 
      
 170 
     | 
    
         
            +
                      currency.disambiguate_symbol
         
     | 
| 
      
 171 
     | 
    
         
            +
                    else
         
     | 
| 
      
 172 
     | 
    
         
            +
                      symbol
         
     | 
| 
      
 173 
     | 
    
         
            +
                    end
         
     | 
| 
      
 174 
     | 
    
         
            +
                  end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                  def symbol_position_from(rules, currency)
         
     | 
| 
      
 177 
     | 
    
         
            +
                    if rules.has_key?(:symbol_position)
         
     | 
| 
      
 178 
     | 
    
         
            +
                      if [:before, :after].include?(rules[:symbol_position])
         
     | 
| 
      
 179 
     | 
    
         
            +
                        return rules[:symbol_position]
         
     | 
| 
      
 180 
     | 
    
         
            +
                      else
         
     | 
| 
      
 181 
     | 
    
         
            +
                        raise ArgumentError, ":symbol_position must be ':before' or ':after'"
         
     | 
| 
      
 182 
     | 
    
         
            +
                      end
         
     | 
| 
      
 183 
     | 
    
         
            +
                    elsif currency.symbol_first?
         
     | 
| 
      
 184 
     | 
    
         
            +
                      :before
         
     | 
| 
      
 185 
     | 
    
         
            +
                    else
         
     | 
| 
      
 186 
     | 
    
         
            +
                      :after
         
     | 
| 
      
 187 
     | 
    
         
            +
                    end
         
     | 
| 
      
 188 
     | 
    
         
            +
                  end
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                  private
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                  # Cleans up formatting rules.
         
     | 
| 
      
 193 
     | 
    
         
            +
                  #
         
     | 
| 
      
 194 
     | 
    
         
            +
                  # @param [Hash] rules
         
     | 
| 
      
 195 
     | 
    
         
            +
                  #
         
     | 
| 
      
 196 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 197 
     | 
    
         
            +
                  def normalize_formatting_rules(rules)
         
     | 
| 
      
 198 
     | 
    
         
            +
                    if rules.size == 0
         
     | 
| 
      
 199 
     | 
    
         
            +
                      rules = {}
         
     | 
| 
      
 200 
     | 
    
         
            +
                    elsif rules.size == 1
         
     | 
| 
      
 201 
     | 
    
         
            +
                      rules = rules.pop
         
     | 
| 
      
 202 
     | 
    
         
            +
                      rules = { rules => true } if rules.is_a?(Symbol)
         
     | 
| 
      
 203 
     | 
    
         
            +
                    end
         
     | 
| 
      
 204 
     | 
    
         
            +
                    rules[:decimal_mark] = rules[:separator] || rules[:decimal_mark]
         
     | 
| 
      
 205 
     | 
    
         
            +
                    rules[:thousands_separator] = rules[:delimiter] || rules[:thousands_separator]
         
     | 
| 
      
 206 
     | 
    
         
            +
                    rules
         
     | 
| 
      
 207 
     | 
    
         
            +
                  end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                  # Applies decimal mark from rules to formatted
         
     | 
| 
      
 210 
     | 
    
         
            +
                  #
         
     | 
| 
      
 211 
     | 
    
         
            +
                  # @param [String] formatted
         
     | 
| 
      
 212 
     | 
    
         
            +
                  # @param [Hash]   rules
         
     | 
| 
      
 213 
     | 
    
         
            +
                  def apply_decimal_mark_from_rules(formatted, rules)
         
     | 
| 
      
 214 
     | 
    
         
            +
                    if rules.has_key?(:decimal_mark) && rules[:decimal_mark]
         
     | 
| 
      
 215 
     | 
    
         
            +
                      # && rules[:decimal_mark] != decimal_mark
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                      regexp_decimal = Regexp.escape(rules[:decimal_mark])
         
     | 
| 
      
 218 
     | 
    
         
            +
                      formatted.sub!(/(.*)(#{regexp_decimal})(.*)\Z/,
         
     | 
| 
      
 219 
     | 
    
         
            +
                                     "\\1#{rules[:decimal_mark]}\\3")
         
     | 
| 
      
 220 
     | 
    
         
            +
                    end
         
     | 
| 
      
 221 
     | 
    
         
            +
                  end
         
     | 
| 
      
 222 
     | 
    
         
            +
                end
         
     | 
| 
      
 223 
     | 
    
         
            +
              end
         
     | 
| 
      
 224 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,151 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module YeshouaCrm
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Currency
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Heuristics
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  # An robust and efficient algorithm for finding currencies in
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # text. Using several algorithms it can find symbols, iso codes and
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # even names of currencies.
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Although not recommendable, it can also attempt to find the given
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # currency in an entire sentence
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # Returns: Array (matched results)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def analyze(str)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    return Analyzer.new(str, search_tree).process
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  private
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  # Build a search tree from the currency database
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def search_tree
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @_search_tree ||= {
         
     | 
| 
      
 21 
     | 
    
         
            +
                      :by_symbol => currencies_by_symbol,
         
     | 
| 
      
 22 
     | 
    
         
            +
                      :by_iso_code => currencies_by_iso_code,
         
     | 
| 
      
 23 
     | 
    
         
            +
                      :by_name => currencies_by_name
         
     | 
| 
      
 24 
     | 
    
         
            +
                    }
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def currencies_by_symbol
         
     | 
| 
      
 28 
     | 
    
         
            +
                    {}.tap do |r|
         
     | 
| 
      
 29 
     | 
    
         
            +
                      table.each do |dummy, c|
         
     | 
| 
      
 30 
     | 
    
         
            +
                        symbol = (c[:symbol]||"").downcase
         
     | 
| 
      
 31 
     | 
    
         
            +
                        symbol.chomp!('.')
         
     | 
| 
      
 32 
     | 
    
         
            +
                        (r[symbol] ||= []) << c
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                        (c[:alternate_symbols]||[]).each do |ac|
         
     | 
| 
      
 35 
     | 
    
         
            +
                          ac = ac.downcase
         
     | 
| 
      
 36 
     | 
    
         
            +
                          ac.chomp!('.')
         
     | 
| 
      
 37 
     | 
    
         
            +
                          (r[ac] ||= []) << c
         
     | 
| 
      
 38 
     | 
    
         
            +
                        end
         
     | 
| 
      
 39 
     | 
    
         
            +
                      end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def currencies_by_iso_code
         
     | 
| 
      
 44 
     | 
    
         
            +
                    {}.tap do |r|
         
     | 
| 
      
 45 
     | 
    
         
            +
                      table.each do |dummy,c|
         
     | 
| 
      
 46 
     | 
    
         
            +
                        (r[c[:iso_code].downcase] ||= []) << c
         
     | 
| 
      
 47 
     | 
    
         
            +
                      end
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def currencies_by_name
         
     | 
| 
      
 52 
     | 
    
         
            +
                    {}.tap do |r|
         
     | 
| 
      
 53 
     | 
    
         
            +
                      table.each do |dummy,c|
         
     | 
| 
      
 54 
     | 
    
         
            +
                        name_parts = c[:name].downcase.split
         
     | 
| 
      
 55 
     | 
    
         
            +
                        name_parts.each {|part| part.chomp!('.')}
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                        # construct one branch per word
         
     | 
| 
      
 58 
     | 
    
         
            +
                        root = r
         
     | 
| 
      
 59 
     | 
    
         
            +
                        while name_part = name_parts.shift
         
     | 
| 
      
 60 
     | 
    
         
            +
                          root = (root[name_part] ||= {})
         
     | 
| 
      
 61 
     | 
    
         
            +
                        end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                        # the leaf is a currency
         
     | 
| 
      
 64 
     | 
    
         
            +
                        (root[:value] ||= []) << c
         
     | 
| 
      
 65 
     | 
    
         
            +
                      end
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  class Analyzer
         
     | 
| 
      
 70 
     | 
    
         
            +
                    attr_reader :search_tree, :words
         
     | 
| 
      
 71 
     | 
    
         
            +
                    attr_accessor :str, :currencies
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                    def initialize str, search_tree
         
     | 
| 
      
 74 
     | 
    
         
            +
                      @str = (str||'').dup
         
     | 
| 
      
 75 
     | 
    
         
            +
                      @search_tree = search_tree
         
     | 
| 
      
 76 
     | 
    
         
            +
                      @currencies = []
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    def process
         
     | 
| 
      
 80 
     | 
    
         
            +
                      format
         
     | 
| 
      
 81 
     | 
    
         
            +
                      return [] if str.empty?
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                      search_by_symbol
         
     | 
| 
      
 84 
     | 
    
         
            +
                      search_by_iso_code
         
     | 
| 
      
 85 
     | 
    
         
            +
                      search_by_name
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                      prepare_reply
         
     | 
| 
      
 88 
     | 
    
         
            +
                    end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                    def format
         
     | 
| 
      
 91 
     | 
    
         
            +
                      str.gsub!(/[\r\n\t]/,'')
         
     | 
| 
      
 92 
     | 
    
         
            +
                      str.gsub!(/[0-9][\.,:0-9]*[0-9]/,'')
         
     | 
| 
      
 93 
     | 
    
         
            +
                      str.gsub!(/[0-9]/, '')
         
     | 
| 
      
 94 
     | 
    
         
            +
                      str.downcase!
         
     | 
| 
      
 95 
     | 
    
         
            +
                      @words = str.split
         
     | 
| 
      
 96 
     | 
    
         
            +
                      @words.each {|word| word.chomp!('.'); word.chomp!(',') }
         
     | 
| 
      
 97 
     | 
    
         
            +
                    end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                    def search_by_symbol
         
     | 
| 
      
 100 
     | 
    
         
            +
                      words.each do |word|
         
     | 
| 
      
 101 
     | 
    
         
            +
                        if found = search_tree[:by_symbol][word]
         
     | 
| 
      
 102 
     | 
    
         
            +
                          currencies.concat(found)
         
     | 
| 
      
 103 
     | 
    
         
            +
                        end
         
     | 
| 
      
 104 
     | 
    
         
            +
                      end
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                    def search_by_iso_code
         
     | 
| 
      
 108 
     | 
    
         
            +
                      words.each do |word|
         
     | 
| 
      
 109 
     | 
    
         
            +
                        if found = search_tree[:by_iso_code][word]
         
     | 
| 
      
 110 
     | 
    
         
            +
                          currencies.concat(found)
         
     | 
| 
      
 111 
     | 
    
         
            +
                        end
         
     | 
| 
      
 112 
     | 
    
         
            +
                      end
         
     | 
| 
      
 113 
     | 
    
         
            +
                    end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                    def search_by_name
         
     | 
| 
      
 116 
     | 
    
         
            +
                      # remember, the search tree by name is a construct of branches and leaf!
         
     | 
| 
      
 117 
     | 
    
         
            +
                      # We need to try every combination of words within the sentence, so we
         
     | 
| 
      
 118 
     | 
    
         
            +
                      # end up with a x^2 equation, which should be fine as most names are either
         
     | 
| 
      
 119 
     | 
    
         
            +
                      # one or two words, and this is multiplied with the words of given sentence
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                      search_words = words.dup
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                      while search_words.length > 0
         
     | 
| 
      
 124 
     | 
    
         
            +
                        root = search_tree[:by_name]
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                        search_words.each do |word|
         
     | 
| 
      
 127 
     | 
    
         
            +
                          if root = root[word]
         
     | 
| 
      
 128 
     | 
    
         
            +
                            if root[:value]
         
     | 
| 
      
 129 
     | 
    
         
            +
                              currencies.concat(root[:value])
         
     | 
| 
      
 130 
     | 
    
         
            +
                            end
         
     | 
| 
      
 131 
     | 
    
         
            +
                          else
         
     | 
| 
      
 132 
     | 
    
         
            +
                            break
         
     | 
| 
      
 133 
     | 
    
         
            +
                          end
         
     | 
| 
      
 134 
     | 
    
         
            +
                        end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                        search_words.delete_at(0)
         
     | 
| 
      
 137 
     | 
    
         
            +
                      end
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                    def prepare_reply
         
     | 
| 
      
 141 
     | 
    
         
            +
                      codes = currencies.map do |currency|
         
     | 
| 
      
 142 
     | 
    
         
            +
                        currency[:iso_code]
         
     | 
| 
      
 143 
     | 
    
         
            +
                      end
         
     | 
| 
      
 144 
     | 
    
         
            +
                      codes.uniq!
         
     | 
| 
      
 145 
     | 
    
         
            +
                      codes.sort!
         
     | 
| 
      
 146 
     | 
    
         
            +
                      codes
         
     | 
| 
      
 147 
     | 
    
         
            +
                    end
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
              end
         
     | 
| 
      
 151 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module YeshouaCrm
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Currency
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Loader
         
     | 
| 
      
 4 
     | 
    
         
            +
                  DATA_PATH = File.expand_path("../../../../config", __FILE__)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  # Loads and returns the currencies stored in JSON files in the config directory.
         
     | 
| 
      
 7 
     | 
    
         
            +
                  #
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def load_currencies
         
     | 
| 
      
 10 
     | 
    
         
            +
                    currencies = parse_currency_file("currency_iso.json")
         
     | 
| 
      
 11 
     | 
    
         
            +
                    # currencies.merge! parse_currency_file("currency_non_iso.json")
         
     | 
| 
      
 12 
     | 
    
         
            +
                    # currencies.merge! parse_currency_file("currency_backwards_compatible.json")
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  private
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def parse_currency_file(filename)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    json = File.read("#{DATA_PATH}/#{filename}")
         
     | 
| 
      
 19 
     | 
    
         
            +
                    json.force_encoding(::Encoding::UTF_8) if defined?(::Encoding)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    JSON.parse(json, :symbolize_names => true)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module YeshouaCrm
         
     | 
| 
      
 2 
     | 
    
         
            +
              module ExternalAssetsHelper
         
     | 
| 
      
 3 
     | 
    
         
            +
                include ActionView::Helpers::JavaScriptHelper
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                def select2_assets
         
     | 
| 
      
 6 
     | 
    
         
            +
                  return if @select2_tag_included
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @select2_tag_included = true
         
     | 
| 
      
 8 
     | 
    
         
            +
                  javascript_include_tag('select2', :plugin => 'yeshoua_crm') + stylesheet_link_tag('select2', :plugin => 'yeshoua_crm')
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def chartjs_assets
         
     | 
| 
      
 12 
     | 
    
         
            +
                  return if @chartjs_tag_included
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @chartjs_tag_included = true
         
     | 
| 
      
 14 
     | 
    
         
            +
                  javascript_include_tag('Chart.bundle.min', :plugin => 'yeshoua_crm')
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,123 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module YeshouaCrm
         
     | 
| 
      
 2 
     | 
    
         
            +
              module FormTagHelper
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Allows include select2 into your views.
         
     | 
| 
      
 4 
     | 
    
         
            +
                #
         
     | 
| 
      
 5 
     | 
    
         
            +
                # ==== Examples
         
     | 
| 
      
 6 
     | 
    
         
            +
                #   select2_tag 'city_id', '<option value="1">Lisbon</option>...'
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   select2_tag 'city_id', options_for_select(...)
         
     | 
| 
      
 8 
     | 
    
         
            +
                #   select2_tag 'tag_list', nil, :multiple => true, :data => [{ id: 0, text: 'deal' }, ...], :tags => true, :include_hidden => false %>
         
     | 
| 
      
 9 
     | 
    
         
            +
                #   select2_tag 'tag_list', options_for_select(...), :multiple => true, :style => 'width: 100%;', :url => '/tags', :placeholder => '+ add tag', :tags => true %>
         
     | 
| 
      
 10 
     | 
    
         
            +
                #
         
     | 
| 
      
 11 
     | 
    
         
            +
                # You may use select_tag options and additional options.
         
     | 
| 
      
 12 
     | 
    
         
            +
                #
         
     | 
| 
      
 13 
     | 
    
         
            +
                # ==== Additional options
         
     | 
| 
      
 14 
     | 
    
         
            +
                # * <tt>:url</tt> Allows searches for remote data using the ajax.
         
     | 
| 
      
 15 
     | 
    
         
            +
                # * <tt>:data</tt> Load dropdown options from a local array if +url+ option not set.
         
     | 
| 
      
 16 
     | 
    
         
            +
                # * <tt>:placeholder</tt> Supports displaying a placeholder value.
         
     | 
| 
      
 17 
     | 
    
         
            +
                # * <tt>:include_hidden</tt> Adds hidden field after select when +multiple+ option true. Default value true.
         
     | 
| 
      
 18 
     | 
    
         
            +
                #
         
     | 
| 
      
 19 
     | 
    
         
            +
                # <b>Note:</b> The HTML specification says when +multiple+ parameter passed to select and all options got deselected
         
     | 
| 
      
 20 
     | 
    
         
            +
                # web browsers do not send any value to server.
         
     | 
| 
      
 21 
     | 
    
         
            +
                #
         
     | 
| 
      
 22 
     | 
    
         
            +
                # In case if you don't want the helper to generate this hidden field you can specify
         
     | 
| 
      
 23 
     | 
    
         
            +
                # <tt>include_hidden: false</tt> option.
         
     | 
| 
      
 24 
     | 
    
         
            +
                #
         
     | 
| 
      
 25 
     | 
    
         
            +
                # Also aliased as: select2
         
     | 
| 
      
 26 
     | 
    
         
            +
                #
         
     | 
| 
      
 27 
     | 
    
         
            +
                #   select2 'city_id', options_for_select(...)
         
     | 
| 
      
 28 
     | 
    
         
            +
                #
         
     | 
| 
      
 29 
     | 
    
         
            +
                def select2_tag(name, option_tags = nil, options = {})
         
     | 
| 
      
 30 
     | 
    
         
            +
                  id = sanitize_to_id(name)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  placeholder = options[:placeholder] || 'Select ...'
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  content_for(:header_tags) { select2_assets }
         
     | 
| 
      
 34 
     | 
    
         
            +
                  result = select_tag(name, option_tags, options)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  if options[:multiple] && options.fetch(:include_hidden, true)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    result << hidden_field_tag("#{name}[]", '')
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  result << javascript_tag(<<-JS)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    $(function () {
         
     | 
| 
      
 41 
     | 
    
         
            +
                        $('select#' + '#{id}').select2({
         
     | 
| 
      
 42 
     | 
    
         
            +
                            #{select2_data_source_options(options)},
         
     | 
| 
      
 43 
     | 
    
         
            +
                            #{select2_tags_options(options)},
         
     | 
| 
      
 44 
     | 
    
         
            +
                            placeholder: '#{placeholder}'
         
     | 
| 
      
 45 
     | 
    
         
            +
                        });
         
     | 
| 
      
 46 
     | 
    
         
            +
                    });
         
     | 
| 
      
 47 
     | 
    
         
            +
                  JS
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                alias select2 select2_tag
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                # Transforms select filter field into select2
         
     | 
| 
      
 53 
     | 
    
         
            +
                #
         
     | 
| 
      
 54 
     | 
    
         
            +
                # ==== Examples
         
     | 
| 
      
 55 
     | 
    
         
            +
                #   transform_to_select2 'issue_tags', url: auto_complete_tags_url
         
     | 
| 
      
 56 
     | 
    
         
            +
                #   transform_to_select2 'manager_id', format_state: 'formatStateWithAvatar', min_input_length: 1, url: '/managers'
         
     | 
| 
      
 57 
     | 
    
         
            +
                #
         
     | 
| 
      
 58 
     | 
    
         
            +
                # ==== Options
         
     | 
| 
      
 59 
     | 
    
         
            +
                # * <tt>:url</tt> Defines URL to search remote data using the ajax.
         
     | 
| 
      
 60 
     | 
    
         
            +
                # * <tt>:format_state</tt> Defines template of search results in the drop-down.
         
     | 
| 
      
 61 
     | 
    
         
            +
                # * <tt>:min_input_length</tt> Minimum number of characters required to start a search. Default value 0.
         
     | 
| 
      
 62 
     | 
    
         
            +
                # * <tt>:width</tt> Sets the width of the control. Default value '60%'.
         
     | 
| 
      
 63 
     | 
    
         
            +
                #
         
     | 
| 
      
 64 
     | 
    
         
            +
                def transform_to_select2(field, options = {})
         
     | 
| 
      
 65 
     | 
    
         
            +
                  return if field.empty?
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  result = ''.html_safe
         
     | 
| 
      
 68 
     | 
    
         
            +
                  unless @transform_to_select2_included
         
     | 
| 
      
 69 
     | 
    
         
            +
                  result << javascript_include_tag('select2_helpers', plugin: 'yeshoua_crm')
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @transform_to_select2_included = true
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  result << javascript_tag(<<-JS)
         
     | 
| 
      
 74 
     | 
    
         
            +
                      select2Filters['#{field}'] = {
         
     | 
| 
      
 75 
     | 
    
         
            +
                          url: '#{options[:url].to_s}',
         
     | 
| 
      
 76 
     | 
    
         
            +
                          formatState: #{options.fetch(:format_state, 'undefined')},
         
     | 
| 
      
 77 
     | 
    
         
            +
                          minimumInputLength: #{options.fetch(:min_input_length, 0)},
         
     | 
| 
      
 78 
     | 
    
         
            +
                          width: '#{options.fetch(:with, '60%')}'
         
     | 
| 
      
 79 
     | 
    
         
            +
                      };
         
     | 
| 
      
 80 
     | 
    
         
            +
                  JS
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                private
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                def select2_data_source_options(options = {})
         
     | 
| 
      
 86 
     | 
    
         
            +
                  if options[:url].to_s.empty?
         
     | 
| 
      
 87 
     | 
    
         
            +
                    "data: #{options.fetch(:data, []).to_json}"
         
     | 
| 
      
 88 
     | 
    
         
            +
                  else
         
     | 
| 
      
 89 
     | 
    
         
            +
                    "ajax: {
         
     | 
| 
      
 90 
     | 
    
         
            +
                         url: '#{options[:url]}',
         
     | 
| 
      
 91 
     | 
    
         
            +
                         dataType: 'json',
         
     | 
| 
      
 92 
     | 
    
         
            +
                         delay: 250,
         
     | 
| 
      
 93 
     | 
    
         
            +
                         data: function (params) {
         
     | 
| 
      
 94 
     | 
    
         
            +
                             return { q: params.term };
         
     | 
| 
      
 95 
     | 
    
         
            +
                         },
         
     | 
| 
      
 96 
     | 
    
         
            +
                         processResults: function (data, params) {
         
     | 
| 
      
 97 
     | 
    
         
            +
                             return { results: data };
         
     | 
| 
      
 98 
     | 
    
         
            +
                         },
         
     | 
| 
      
 99 
     | 
    
         
            +
                         cache: true
         
     | 
| 
      
 100 
     | 
    
         
            +
                     }"
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                def select2_tags_options(options = {})
         
     | 
| 
      
 105 
     | 
    
         
            +
                  if options.fetch(:tags, false)
         
     | 
| 
      
 106 
     | 
    
         
            +
                    "tags: true,
         
     | 
| 
      
 107 
     | 
    
         
            +
                     tokenSeparators: [','],
         
     | 
| 
      
 108 
     | 
    
         
            +
                     createTag: function (params) {
         
     | 
| 
      
 109 
     | 
    
         
            +
                         var term = $.trim(params.term);
         
     | 
| 
      
 110 
     | 
    
         
            +
                         if (term === '' || term.indexOf(',') > -1) {
         
     | 
| 
      
 111 
     | 
    
         
            +
                             return null; // Return null to disable tag creation
         
     | 
| 
      
 112 
     | 
    
         
            +
                         }
         
     | 
| 
      
 113 
     | 
    
         
            +
                         return {
         
     | 
| 
      
 114 
     | 
    
         
            +
                             id: term,
         
     | 
| 
      
 115 
     | 
    
         
            +
                             text: term
         
     | 
| 
      
 116 
     | 
    
         
            +
                         }
         
     | 
| 
      
 117 
     | 
    
         
            +
                     }"
         
     | 
| 
      
 118 
     | 
    
         
            +
                  else
         
     | 
| 
      
 119 
     | 
    
         
            +
                    'tags: false'
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
              end
         
     | 
| 
      
 123 
     | 
    
         
            +
            end
         
     |