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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +11 -0
  3. data/lib/yeshoua_crm.rb +87 -0
  4. data/lib/yeshoua_crm/acts_as_draftable/draft.rb +40 -0
  5. data/lib/yeshoua_crm/acts_as_draftable/rcrm_acts_as_draftable.rb +154 -0
  6. data/lib/yeshoua_crm/acts_as_list/list.rb +282 -0
  7. data/lib/yeshoua_crm/acts_as_taggable/rcrm_acts_as_taggable.rb +350 -0
  8. data/lib/yeshoua_crm/acts_as_taggable/tag.rb +81 -0
  9. data/lib/yeshoua_crm/acts_as_taggable/tag_list.rb +111 -0
  10. data/lib/yeshoua_crm/acts_as_taggable/tagging.rb +16 -0
  11. data/lib/yeshoua_crm/acts_as_viewed/rcrm_acts_as_viewed.rb +274 -0
  12. data/lib/yeshoua_crm/acts_as_votable/rcrm_acts_as_votable.rb +80 -0
  13. data/lib/yeshoua_crm/acts_as_votable/rcrm_acts_as_voter.rb +20 -0
  14. data/lib/yeshoua_crm/acts_as_votable/votable.rb +323 -0
  15. data/lib/yeshoua_crm/acts_as_votable/vote.rb +28 -0
  16. data/lib/yeshoua_crm/acts_as_votable/voter.rb +131 -0
  17. data/lib/yeshoua_crm/assets_manager.rb +43 -0
  18. data/lib/yeshoua_crm/currency.rb +439 -0
  19. data/lib/yeshoua_crm/currency/formatting.rb +224 -0
  20. data/lib/yeshoua_crm/currency/heuristics.rb +151 -0
  21. data/lib/yeshoua_crm/currency/loader.rb +24 -0
  22. data/lib/yeshoua_crm/helpers/external_assets_helper.rb +17 -0
  23. data/lib/yeshoua_crm/helpers/form_tag_helper.rb +123 -0
  24. data/lib/yeshoua_crm/helpers/tags_helper.rb +13 -0
  25. data/lib/yeshoua_crm/helpers/vote_helper.rb +35 -0
  26. data/lib/yeshoua_crm/liquid/drops/cells_drop.rb +86 -0
  27. data/lib/yeshoua_crm/liquid/drops/issues_drop.rb +66 -0
  28. data/lib/yeshoua_crm/liquid/drops/news_drop.rb +54 -0
  29. data/lib/yeshoua_crm/liquid/drops/users_drop.rb +72 -0
  30. data/lib/yeshoua_crm/liquid/filters/arrays.rb +177 -0
  31. data/lib/yeshoua_crm/liquid/filters/base.rb +208 -0
  32. data/lib/yeshoua_crm/money_helper.rb +65 -0
  33. data/lib/yeshoua_crm/version.rb +3 -0
  34. data/test/acts_as_draftable/draft_test.rb +29 -0
  35. data/test/acts_as_draftable/rcrm_acts_as_draftable_test.rb +185 -0
  36. data/test/acts_as_taggable/rcrm_acts_as_taggable_test.rb +345 -0
  37. data/test/acts_as_taggable/tag_list_test.rb +34 -0
  38. data/test/acts_as_taggable/tag_test.rb +72 -0
  39. data/test/acts_as_taggable/tagging_test.rb +15 -0
  40. data/test/acts_as_viewed/rcrm_acts_as_viewed_test.rb +47 -0
  41. data/test/acts_as_votable/rcrm_acts_as_votable_test.rb +19 -0
  42. data/test/acts_as_votable/rcrm_acts_as_voter_test.rb +14 -0
  43. data/test/acts_as_votable/votable_test.rb +507 -0
  44. data/test/acts_as_votable/voter_test.rb +296 -0
  45. data/test/currency_test.rb +292 -0
  46. data/test/liquid/drops/issues_drop_test.rb +34 -0
  47. data/test/liquid/drops/news_drop_test.rb +38 -0
  48. data/test/liquid/drops/projects_drop_test.rb +44 -0
  49. data/test/liquid/drops/uses_drop_test.rb +36 -0
  50. data/test/liquid/filters/arrays_filter_test.rb +24 -0
  51. data/test/liquid/filters/base_filter_test.rb +63 -0
  52. data/test/liquid/liquid_helper.rb +32 -0
  53. data/test/models/issue.rb +14 -0
  54. data/test/models/news.rb +3 -0
  55. data/test/models/project.rb +8 -0
  56. data/test/models/user.rb +11 -0
  57. data/test/models/vote_classes.rb +33 -0
  58. data/test/money_helper_test.rb +12 -0
  59. data/test/schema.rb +121 -0
  60. data/test/tags_helper_test.rb +29 -0
  61. data/test/test_helper.rb +66 -0
  62. data/test/vote_helper_test.rb +28 -0
  63. data/yeshoua_crm.gemspec +28 -0
  64. metadata +206 -0
@@ -0,0 +1,13 @@
1
+ module YeshouaCrm
2
+ module TagsHelper
3
+ # See the README for an example using tag_cloud.
4
+ def tag_cloud(tags, classes)
5
+ return if tags.empty?
6
+ max_count = tags.sort_by(&:count).last.count.to_f
7
+ tags.each do |tag|
8
+ index = ((tag.count / max_count) * (classes.size - 1)).round
9
+ yield tag, classes[index]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module YeshouaCrm
2
+ module ActsAsVotable
3
+ module Helpers
4
+ # this helper provides methods that help find what words are
5
+ # up votes and what words are down votes
6
+ #
7
+ # It can be called
8
+ #
9
+ # votable_object.votable_words.that_mean_true
10
+ #
11
+ module Words
12
+ def votable_words
13
+ VotableWords
14
+ end
15
+ end
16
+
17
+ class VotableWords
18
+ def self.that_mean_true
19
+ ['up', 'upvote', 'like', 'liked', 'positive', 'yes', 'good', 'true', 1, true]
20
+ end
21
+
22
+ def self.that_mean_false
23
+ ['down', 'downvote', 'dislike', 'disliked', 'negative', 'no', 'bad', 'false', 0, false]
24
+ end
25
+
26
+ # check is word is a true or bad vote
27
+ # if the word is unknown, then it counts it as a true/good
28
+ # vote. this exists to allow all voting to be good by default
29
+ def self.meaning_of(word)
30
+ !that_mean_false.include?(word)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,86 @@
1
+ module YeshouaCrm
2
+ module Liquid
3
+ class CellsDrop < ::Liquid::Drop
4
+
5
+ def self.default_drop
6
+ self.new Cell.visible.order(:name)
7
+ end
8
+
9
+ def initialize(cells)
10
+ @cells = cells
11
+ end
12
+
13
+ def before_method(identifier)
14
+ cell = @cells.where(:identifier => identifier).first || Cell.new
15
+ CellDrop.new cell
16
+ end
17
+
18
+ def all
19
+ @all ||= @cells.map do |cell|
20
+ CellDrop.new cell
21
+ end
22
+ end
23
+
24
+ def active
25
+ @active ||= @cells.select(&:active?).map do |cell|
26
+ CellDrop.new cell
27
+ end
28
+ end
29
+
30
+ def each(&block)
31
+ all.each(&block)
32
+ end
33
+
34
+ def size
35
+ @cells.size
36
+ end
37
+ end
38
+
39
+ class CellDrop < ::Liquid::Drop
40
+ include ActionView::Helpers::UrlHelper
41
+
42
+ delegate :id,
43
+ :identifier,
44
+ :name,
45
+ :is_public,
46
+ :description,
47
+ :visible?,
48
+ :active?,
49
+ :archived?,
50
+ :short_description,
51
+ :start_date,
52
+ :due_date,
53
+ :overdue?,
54
+ :completed_percent,
55
+ :to => :@cell
56
+
57
+ def initialize(cell)
58
+ @cell = cell
59
+ end
60
+
61
+ def link
62
+ link_to @cell.name, self.url
63
+ end
64
+
65
+ def url
66
+ Rails.application.routes.url_helpers.cell_path(@cell)
67
+ end
68
+
69
+ def issues
70
+ @issues ||= IssuesDrop.new @cell.issues.visible
71
+ end
72
+
73
+ def users
74
+ @users ||= UsersDrop.new @cell.users
75
+ end
76
+
77
+ def subcells
78
+ @subcells ||= CellsDrop.new @cell.children
79
+ end
80
+
81
+ def custom_field_values
82
+ @cell.custom_field_values
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,66 @@
1
+ module YeshouaCrm
2
+ module Liquid
3
+ class IssuesDrop < ::Liquid::Drop
4
+ def initialize(issues)
5
+ @issues = issues
6
+ end
7
+
8
+ def before_method(id)
9
+ issue = @issues.where(:id => id).first || Issue.new
10
+ IssueDrop.new issue
11
+ end
12
+
13
+ def all
14
+ @all ||= @issues.map do |issue|
15
+ IssueDrop.new issue
16
+ end
17
+ end
18
+
19
+ def each(&block)
20
+ all.each(&block)
21
+ end
22
+
23
+ def size
24
+ @issues.size
25
+ end
26
+ end
27
+
28
+ class IssueDrop < ::Liquid::Drop
29
+ include ActionView::Helpers::UrlHelper
30
+
31
+ delegate :id,
32
+ :subject,
33
+ :description,
34
+ :visible?,
35
+ :open?,
36
+ :start_date,
37
+ :due_date,
38
+ :overdue?,
39
+ :completed_percent,
40
+ :updated_on,
41
+ :created_on,
42
+ :to => :@issue
43
+
44
+ def initialize(issue)
45
+ @issue = issue
46
+ end
47
+
48
+ def link
49
+ link_to @issue.subject, self.url
50
+ end
51
+
52
+ def url
53
+ Rails.application.routes.url_helpers.issue_path(@issue)
54
+ end
55
+
56
+ def author
57
+ @user ||= UserDrop.new(@issue.author)
58
+ end
59
+
60
+ def custom_field_values
61
+ @issue.custom_field_values
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,54 @@
1
+ module YeshouaCrm
2
+ module Liquid
3
+ class NewssDrop < ::Liquid::Drop
4
+
5
+ def self.default_drop
6
+ self.new News.visible.order("#{News.table_name}.created_on")
7
+ end
8
+
9
+ def initialize(newss)
10
+ @newss = newss
11
+ end
12
+
13
+ def before_method(id)
14
+ news = @newss.where(:id => id).first || News.new
15
+ NewsDrop.new news
16
+ end
17
+
18
+ def last
19
+ NewsDrop.new News.last
20
+ end
21
+
22
+ def all
23
+ @all ||= @newss.map do |news|
24
+ NewsDrop.new news
25
+ end
26
+ end
27
+
28
+ def each(&block)
29
+ all.each(&block)
30
+ end
31
+
32
+ def size
33
+ @newss.size
34
+ end
35
+ end
36
+
37
+ class NewsDrop < ::Liquid::Drop
38
+ delegate :id, :title, :summary, :description, :visible?, :commentable?, :to => :@news
39
+
40
+ def initialize(news)
41
+ @news = news
42
+ end
43
+
44
+ def author
45
+ UserDrop.new @news.author
46
+ end
47
+
48
+ def custom_field_values
49
+ @news.custom_field_values
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,72 @@
1
+ module YeshouaCrm
2
+ module Liquid
3
+ class UsersDrop < ::Liquid::Drop
4
+
5
+ def self.default_drop
6
+ self.new User.sorted
7
+ end
8
+
9
+ def initialize(users)
10
+ @users = users
11
+ end
12
+
13
+ def before_method(login)
14
+ user = @users.where(:login => login).first || User.new
15
+ UserDrop.new user
16
+ end
17
+
18
+ def current
19
+ UserDrop.new User.current
20
+ end
21
+
22
+ def all
23
+ @all ||= @users.map do |user|
24
+ UserDrop.new user
25
+ end
26
+ end
27
+
28
+ def each(&block)
29
+ all.each(&block)
30
+ end
31
+
32
+ def size
33
+ @users.size
34
+ end
35
+ end
36
+
37
+ class UserDrop < ::Liquid::Drop
38
+ delegate :id, :name, :firstname, :lastname, :mail, :active?, :admin?, :logged?, :language, :to => :@user
39
+
40
+ def initialize(user)
41
+ @user = user
42
+ end
43
+
44
+ def avatar
45
+ ApplicationController.helpers.avatar(@user)
46
+ end
47
+
48
+ def name
49
+ @user.name
50
+ end
51
+
52
+ def permissions
53
+ roles = @user.memberships.collect { |m| m.roles }.flatten.uniq
54
+ roles << (@user.logged? ? Role.non_member : Role.anonymous)
55
+ roles.map(&:permissions).flatten.uniq.map(&:to_s)
56
+ end
57
+
58
+ def groups
59
+ @user.groups.map(&:name)
60
+ end
61
+
62
+ def cells
63
+ CellsDrop.new @user.memberships.map(&:cell).flatten.select(&:visible?).uniq
64
+ end
65
+
66
+ def custom_field_values
67
+ @user.custom_field_values
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,177 @@
1
+ module YeshouaCrm
2
+ module Liquid
3
+ module Filters
4
+ module Arrays
5
+
6
+ # Get the first element of the passed in array
7
+ #
8
+ # Example:
9
+ # {{ product.images | first | to_img }}
10
+ #
11
+ # {{ product.images | first: 3 }}
12
+ #
13
+ def first(array, count=1)
14
+ (count > 1 ? array.first(count) : array.first) if array.respond_to?(:first)
15
+ end
16
+
17
+ # Convert the input into json string
18
+ #
19
+ # input - The Array or Hash to be converted
20
+ #
21
+ # Returns the converted json string
22
+ def jsonify(input)
23
+ as_liquid(input).to_json
24
+ end
25
+
26
+ # Group an array of items by a property
27
+ #
28
+ # input - the inputted Enumerable
29
+ # property - the property
30
+ #
31
+ # Returns an array of Hashes, each looking something like this:
32
+ # {"name" => "larry"
33
+ # "items" => [...] } # all the items where `property` == "larry"
34
+ def group_by(input, property)
35
+ if groupable?(input)
36
+ input.group_by { |item| item_property(item, property).to_s }.each_with_object([]) do |item, array|
37
+ array << {
38
+ "name" => item.first,
39
+ "items" => item.last,
40
+ "size" => item.last.size
41
+ }
42
+ end
43
+ else
44
+ input
45
+ end
46
+ end
47
+
48
+ # Filter an array of objects
49
+ #
50
+ # input - the object array
51
+ # property - property within each object to filter by
52
+ # value - desired value
53
+ #
54
+ # Returns the filtered array of objects
55
+ def where(input, property, value, operator='==')
56
+ return input unless input.respond_to?(:select)
57
+ input = input.values if input.is_a?(Hash)
58
+ if operator == '=='
59
+ input.select do |object|
60
+ Array(item_property(object, property)).map(&:to_s).include?(value.to_s)
61
+ end || []
62
+ elsif operator == '<>'
63
+ input.select do |object|
64
+ !Array(item_property(object, property)).map(&:to_s).include?(value.to_s)
65
+ end || []
66
+ elsif operator == '>'
67
+ input.select do |object|
68
+ item_property(object, property) > value
69
+ end || []
70
+ elsif operator == '<'
71
+ input.select do |object|
72
+ item_property(object, property) < value
73
+ end || []
74
+ elsif operator == 'match'
75
+ input.select do |object|
76
+ Array(item_property(object, property)).map(&:to_s).any?{|i| i.match(value.to_s)}
77
+ end || []
78
+ else
79
+ []
80
+ end
81
+ end
82
+
83
+ # Filter an array of objects by tags
84
+ #
85
+ # input - the object array
86
+ # tags - quoted tags list divided by comma
87
+ # match - (all- defaut, any, exclude)
88
+ #
89
+ # Returns the filtered array of objects
90
+ def tagged_with(input, tags, match='all')
91
+ return input unless input.respond_to?(:select)
92
+ input = input.values if input.is_a?(Hash)
93
+ tag_list = input.is_a?(Array) ? tags.sort : tags.split(',').map(&:strip).sort
94
+ case match
95
+ when "all"
96
+ input.select do |object|
97
+ object.respond_to?(:tag_list) &&
98
+ (tag_list - Array(item_property(object, 'tag_list')).map(&:to_s).sort).empty?
99
+ end || []
100
+ when "any"
101
+ input.select do |object|
102
+ object.respond_to?(:tag_list) &&
103
+ (tag_list & Array(item_property(object, 'tag_list')).map(&:to_s).sort).any?
104
+ end || []
105
+ when "exclude"
106
+ input.select do |object|
107
+ object.respond_to?(:tag_list) &&
108
+ (tag_list & Array(item_property(object, 'tag_list')).map(&:to_s).sort).empty?
109
+ end || []
110
+ else
111
+ []
112
+ end
113
+ end
114
+
115
+ # Sort an array of objects
116
+ #
117
+ # input - the object array
118
+ # property - property within each object to filter by
119
+ # nils ('first' | 'last') - nils appear before or after non-nil values
120
+ #
121
+ # Returns the filtered array of objects
122
+ def sort(input, property = nil, nils = "first")
123
+ if input.nil?
124
+ raise ArgumentError, "Cannot sort a null object."
125
+ end
126
+ if property.nil?
127
+ input.sort
128
+ else
129
+ if nils == "first"
130
+ order = - 1
131
+ elsif nils == "last"
132
+ order = + 1
133
+ else
134
+ raise ArgumentError, "Invalid nils order: " \
135
+ "'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
136
+ end
137
+
138
+ sort_input(input, property, order)
139
+ end
140
+ end
141
+
142
+ def pop(array, input = 1)
143
+ return array unless array.is_a?(Array)
144
+ new_ary = array.dup
145
+ new_ary.pop(input.to_i || 1)
146
+ new_ary
147
+ end
148
+
149
+ def push(array, input)
150
+ return array unless array.is_a?(Array)
151
+ new_ary = array.dup
152
+ new_ary.push(input)
153
+ new_ary
154
+ end
155
+
156
+ def shift(array, input = 1)
157
+ return array unless array.is_a?(Array)
158
+ new_ary = array.dup
159
+ new_ary.shift(input.to_i || 1)
160
+ new_ary
161
+ end
162
+
163
+ def unshift(array, input)
164
+ return array unless array.is_a?(Array)
165
+ new_ary = array.dup
166
+ new_ary.unshift(input)
167
+ new_ary
168
+ end
169
+
170
+ private
171
+
172
+ end # module ArrayFilters
173
+ end
174
+ end
175
+
176
+ ::Liquid::Template.register_filter(YeshouaCrm::Liquid::Filters::Arrays)
177
+ end