fakecrm 0.9.9.beta1

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 (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +76 -0
  7. data/Rakefile +113 -0
  8. data/bin/fakecrm +37 -0
  9. data/fakecrm.gemspec +34 -0
  10. data/lib/fakecrm/application.rb +85 -0
  11. data/lib/fakecrm/configuration.rb +8 -0
  12. data/lib/fakecrm/drop.rb +59 -0
  13. data/lib/fakecrm/embedded.rb +32 -0
  14. data/lib/fakecrm/fetch.rb +139 -0
  15. data/lib/fakecrm/initialize.rb +16 -0
  16. data/lib/fakecrm/localized_dm.rb +12 -0
  17. data/lib/fakecrm/resource/account.rb +33 -0
  18. data/lib/fakecrm/resource/activity.rb +57 -0
  19. data/lib/fakecrm/resource/contact.rb +51 -0
  20. data/lib/fakecrm/resource/custom_attribute.rb +20 -0
  21. data/lib/fakecrm/resource/custom_type.rb +96 -0
  22. data/lib/fakecrm/resource/event.rb +52 -0
  23. data/lib/fakecrm/resource/event_contact.rb +21 -0
  24. data/lib/fakecrm/resource/extensions/kinds.rb +26 -0
  25. data/lib/fakecrm/resource/extensions/type_extender.rb +42 -0
  26. data/lib/fakecrm/resource/extensions/type_extension.rb +55 -0
  27. data/lib/fakecrm/resource/mailing.rb +30 -0
  28. data/lib/fakecrm/resource/password.rb +17 -0
  29. data/lib/fakecrm/resource/role.rb +18 -0
  30. data/lib/fakecrm/resource/template.rb +41 -0
  31. data/lib/fakecrm/resource/views/resource_view.rb +90 -0
  32. data/lib/fakecrm/resources.rb +11 -0
  33. data/lib/fakecrm/server/accounts.rb +39 -0
  34. data/lib/fakecrm/server/activities.rb +39 -0
  35. data/lib/fakecrm/server/contacts.rb +118 -0
  36. data/lib/fakecrm/server/custom_types.rb +34 -0
  37. data/lib/fakecrm/server/event_contacts.rb +38 -0
  38. data/lib/fakecrm/server/events.rb +47 -0
  39. data/lib/fakecrm/server/mailings.rb +44 -0
  40. data/lib/fakecrm/server/roles.rb +44 -0
  41. data/lib/fakecrm/server/templates.rb +24 -0
  42. data/lib/fakecrm/server.rb +37 -0
  43. data/lib/fakecrm/version.rb +5 -0
  44. data/lib/fakecrm.rb +36 -0
  45. data/locales/de.yml +25 -0
  46. data/locales/en.yml +25 -0
  47. data/test/embedded/.gitignore +15 -0
  48. data/test/embedded/Gemfile +6 -0
  49. data/test/embedded/Rakefile +7 -0
  50. data/test/embedded/app/models/.gitkeep +0 -0
  51. data/test/embedded/config/application.rb +44 -0
  52. data/test/embedded/config/boot.rb +6 -0
  53. data/test/embedded/config/environment.rb +5 -0
  54. data/test/embedded/config/environments/development.rb +20 -0
  55. data/test/embedded/config/environments/test.rb +21 -0
  56. data/test/embedded/config/initializers/fakecrm.rb +8 -0
  57. data/test/embedded/config/initializers/secret_token.rb +7 -0
  58. data/test/embedded/config/initializers/session_store.rb +8 -0
  59. data/test/embedded/config/initializers/wrap_parameters.rb +14 -0
  60. data/test/embedded/config/locales/en.yml +5 -0
  61. data/test/embedded/config/routes.rb +2 -0
  62. data/test/embedded/config.ru +4 -0
  63. data/test/embedded/lib/assets/.gitkeep +0 -0
  64. data/test/embedded/lib/tasks/.gitkeep +0 -0
  65. data/test/embedded/log/.gitkeep +0 -0
  66. data/test/embedded/script/rails +6 -0
  67. metadata +301 -0
@@ -0,0 +1,33 @@
1
+ # -*- encoding : utf-8 -*-
2
+ #
3
+ module Fakecrm
4
+ class Account
5
+ include DataMapper::Resource
6
+
7
+ property :id, Serial
8
+ property :name, String, :required => true
9
+
10
+ property :account_group, String
11
+ property :country, String
12
+ property :extended_address, String
13
+ property :home_page, String
14
+ property :locality, String
15
+ property :merged_into_id, String
16
+ property :org_name_address, String
17
+ property :org_unit_address, String
18
+ property :phone, String
19
+ property :postalcode, String
20
+ property :region, String
21
+ property :street_address, String
22
+ property :want_geo_location, Boolean
23
+
24
+ property :created_at, DateTime
25
+ property :changed_at, DateTime
26
+ property :updated_at, DateTime
27
+ property :deleted_at, ParanoidDateTime
28
+
29
+ property :updated_by, String, :default => 'root'
30
+
31
+ end
32
+ end
33
+
@@ -0,0 +1,57 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/extensions/kinds'
3
+
4
+ require 'fakecrm/resource/account'
5
+ require 'fakecrm/resource/contact'
6
+ require 'fakecrm/resource/custom_type'
7
+
8
+ module Fakecrm
9
+ class Activity
10
+ include DataMapper::Resource
11
+
12
+ include Kinds
13
+
14
+ belongs_to :account, :required => false
15
+ belongs_to :contact, :required => false
16
+
17
+ property :id, Serial
18
+ property :title, String, :required => true
19
+ property :appointment_dtend_at, DateTime
20
+ property :appointment_dtstart_at, DateTime
21
+ property :appointment_location, String
22
+ property :email_cc, String
23
+ property :state, String
24
+ property :priority, Integer
25
+ property :tags, CommaSeparatedList
26
+ property :created_at, DateTime
27
+ property :changed_at, DateTime
28
+ property :updated_at, DateTime
29
+ property :deleted_at, ParanoidDateTime
30
+
31
+ property :comments, Json # FIXME: i'm not sure it will work
32
+
33
+ property :updated_by, String, :default => 'root'
34
+
35
+
36
+ validates_with_method :state, :method => :check_state
37
+ validates_presence_of :title
38
+
39
+ def custom_type
40
+ CustomType.get!(self.kind) unless self.kind.nil?
41
+ end
42
+
43
+ def check_state
44
+ custom_type = self.custom_type
45
+ if !custom_type.nil? && !custom_type.states.nil? && !custom_type.states.empty?
46
+ if self.state.nil? || !custom_type.states.include?(self.state)
47
+ # FIXME: localization
48
+ return [false, 'ist kein gültiger Wert']
49
+ end
50
+ end
51
+
52
+ return true
53
+ end
54
+
55
+ end
56
+ end
57
+
@@ -0,0 +1,51 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/account'
3
+
4
+ module Fakecrm
5
+ class Contact
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+ property :first_name, String
10
+ property :last_name, String, :required => true
11
+
12
+ property :email, String
13
+ property :login, String, :unique => true
14
+
15
+ belongs_to :account, :required => false
16
+ property :country, String
17
+ property :extended_address, String
18
+ property :fax, String
19
+ property :gender, Enum['M', 'F', 'N'], :required => true
20
+ property :job_title, String
21
+ property :language, String, :required => true
22
+ property :locality, String
23
+ property :merged_into_id, String
24
+ property :mobile_phone, String
25
+ property :name_prefix, String
26
+ property :org_name_address, String
27
+ property :org_unit_address, String
28
+ property :phone, String
29
+ property :postalcode, String
30
+ property :region, String
31
+ property :street_address, String
32
+ property :want_email, Boolean
33
+ property :want_geo_location, Boolean
34
+ property :want_phonecall, Boolean
35
+ property :want_snailmail, Boolean
36
+
37
+ property :role_names, CommaSeparatedList, :default => ''
38
+
39
+ property :created_at, DateTime
40
+ property :changed_at, DateTime # FIXME: doesn't work automatically
41
+ property :updated_at, DateTime
42
+ property :deleted_at, ParanoidDateTime
43
+
44
+ property :updated_by, String, :default => 'root'
45
+
46
+ before :save do
47
+ self.country = self.country.upcase unless self.country.nil?
48
+ end
49
+ end
50
+ end
51
+
@@ -0,0 +1,20 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/custom_type'
3
+
4
+ module Fakecrm
5
+ class CustomAttribute
6
+ include DataMapper::Resource
7
+
8
+ belongs_to :custom_type
9
+
10
+ property :id, Serial
11
+ property :name, String, :required => true
12
+ property :title, String
13
+ property :type, Enum["string", "text", "enum", "multienum"], :required => true
14
+ property :mandatory, Boolean, :default => false
15
+ property :max_length, String, :default => 100
16
+ property :valid_values, CommaSeparatedList
17
+
18
+ end
19
+ end
20
+
@@ -0,0 +1,96 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/extensions/type_extender'
3
+
4
+ # workaround circular reference
5
+ module Fakecrm
6
+ class CustomType
7
+ include DataMapper::Resource
8
+
9
+ property :id, String, :unique => true, :key => true # default will not work here
10
+ property :name, String, :required => true, :length => 20
11
+ end
12
+ end
13
+
14
+ require 'fakecrm/resource/custom_attribute'
15
+
16
+ # workaround circular reference
17
+ module Fakecrm
18
+ class CustomType
19
+
20
+ property :kind, Enum["Activity", "Account", "Event", "Contact", "EventContact"], :required => true
21
+ property :icon_css_class, String
22
+
23
+ # only one entry for 'Contact' possible
24
+ validates_uniqueness_of :kind, :if => lambda { |c| c.kind == 'Contact' }
25
+
26
+ # only for activity && event_contact
27
+ property :states, CommaSeparatedList
28
+
29
+ has n, :custom_attributes
30
+
31
+ def activity?
32
+ self.kind == 'Activity'
33
+ end
34
+
35
+ # setting name for the first time also sets id
36
+ def name=(new_name)
37
+ if self.id.nil?
38
+ if self.kind == "EventContact"
39
+ self.id = SecureRandom.hex
40
+ else
41
+ self.id = new_name
42
+ end
43
+ end
44
+
45
+ super
46
+ end
47
+
48
+ # This is neccessary because updating DM associations is BROKEN
49
+ def custom_attributes=(custom_attributes)
50
+ if custom_attributes
51
+ existing_attributes = self.custom_attributes.all
52
+ existing_attributes.each do |existing_attribute|
53
+ if !(custom_attributes.find {|c| (c[:name] || c["name"]) == existing_attribute.name})
54
+ existing_attribute.destroy
55
+ end
56
+ end
57
+
58
+ custom_attributes.each do |custom_attribute|
59
+ name = custom_attribute["name"] || custom_attribute[:name]
60
+ c = self.custom_attributes.first(:name => name)
61
+ if c
62
+ c.attributes = custom_attribute
63
+ else
64
+ self.custom_attributes.new(custom_attribute)
65
+ end
66
+ end
67
+ @dm_is_broken = true
68
+ end
69
+ attribute_set(:custom_attributes, self.custom_attributes)
70
+ end
71
+
72
+ after :save, :propagate_type_extension
73
+
74
+ def propagate_type_extension
75
+ ::Fakecrm.logger.debug "Installing custom attributes@ kind=#{self.kind} name=#{self.name}"
76
+ ::Fakecrm::TypeExtender.new(self).extend!
77
+ end
78
+
79
+ def dirty_self?
80
+ # This forces DM to save after changing custom attributes
81
+ # We need this for our callback
82
+ # Did I mention that DM associations ARE BROKEN?
83
+ @dm_is_broken || super
84
+ ensure
85
+ @dm_is_broken = false # NOT REALLY
86
+ end
87
+
88
+ class << self
89
+ def virtual_properties
90
+ [:custom_attributes]
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+
@@ -0,0 +1,52 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/extensions/kinds'
3
+
4
+ require 'fakecrm/resource/custom_type'
5
+
6
+ module Fakecrm
7
+ class Event
8
+ include DataMapper::Resource
9
+
10
+ include Kinds
11
+
12
+ property :id, Serial
13
+ property :title, String, :required => true, :message => 'muss ausgefüllt werden'
14
+
15
+ property :dtstart_at, DateTime, :required => true
16
+ property :dtend_at, DateTime, :required => true
17
+
18
+ property :event_set, String
19
+ property :location, String
20
+
21
+ property :created_at, DateTime
22
+ property :changed_at, DateTime
23
+ property :updated_at, DateTime
24
+ property :deleted_at, ParanoidDateTime
25
+
26
+ property :updated_by, String, :default => 'root'
27
+
28
+ class << self
29
+ def virtual_properties
30
+ [:custom_attributes]
31
+ end
32
+ end
33
+
34
+ def custom_type
35
+ CustomType.first_or_create(:kind => 'EventContact', :name => self.kind)
36
+ end
37
+
38
+ def custom_attributes
39
+ custom_type ? custom_type.custom_attributes : []
40
+ end
41
+
42
+ def custom_attributes=(new_attributes)
43
+ custom_type.update({"custom_attributes"=>new_attributes})
44
+ end
45
+
46
+ def attributes=(attributes)
47
+ custom_attributes = attributes.delete("custom_attributes") || attributes.delete(:custom_attributes) || []
48
+ super(attributes) && (custom_attributes.empty? || (self.custom_attributes = custom_attributes))
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Fakecrm
3
+ class EventContact
4
+ include DataMapper::Resource
5
+
6
+ property :id, Serial
7
+ property :state, Enum['unregistered', 'registered', 'attended', 'refused', 'noshow'], :required => true
8
+
9
+ property :created_at, DateTime
10
+ property :changed_at, DateTime
11
+ property :updated_at, DateTime
12
+ property :deleted_at, ParanoidDateTime
13
+
14
+ property :updated_by, String, :default => 'root'
15
+
16
+ belongs_to :event, :required => true
17
+ belongs_to :contact, :required => true
18
+
19
+ end
20
+ end
21
+
@@ -0,0 +1,26 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/custom_type'
3
+
4
+ module Fakecrm
5
+ module Kinds
6
+ def one_of_a_kind?
7
+ true
8
+ end
9
+ def self.included(base)
10
+ base.class_eval do
11
+ property :kind, ::DataMapper::Property::String, :required => true
12
+
13
+ validates_with_method :kind, :method => :check_kind
14
+
15
+ def check_kind
16
+ if CustomType.first(:name => self.kind, :kind => self.class.name.split('::').last)
17
+ return true
18
+ else
19
+ return [false, "Custom type #{self.kind} not found"]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,42 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/account'
3
+ require 'fakecrm/resource/activity'
4
+ require 'fakecrm/resource/contact'
5
+ require 'fakecrm/resource/event'
6
+ require 'fakecrm/resource/event_contact'
7
+
8
+ require 'fakecrm/resource/extensions/type_extension'
9
+
10
+ require 'dm-types'
11
+
12
+ module Fakecrm
13
+ class TypeExtender
14
+ def initialize(custom_type)
15
+ self.custom_type = custom_type
16
+ end
17
+
18
+ def extend!
19
+ custom_attributes = self.custom_type.custom_attributes
20
+ case self.custom_type.id
21
+ when 'contact'
22
+ TypeExtension.new(Contact).replace!(custom_attributes)
23
+ when 'account'
24
+ TypeExtension.new(Account).replace!(custom_attributes)
25
+ else
26
+ case self.custom_type.kind
27
+ when 'Event'
28
+ TypeExtension.new(Event).add!(custom_attributes)
29
+ when 'Activity'
30
+ TypeExtension.new(Activity).add!(custom_attributes)
31
+ when 'EventContact'
32
+ TypeExtension.new(EventContact).add!(custom_attributes)
33
+ else
34
+ true
35
+ end
36
+ end
37
+ end
38
+
39
+ attr_accessor :custom_type
40
+ end
41
+ end
42
+
@@ -0,0 +1,55 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Fakecrm
3
+ class TypeExtension
4
+ def initialize(resource)
5
+ self.resource = resource
6
+ end
7
+
8
+ def replace!(custom_attributes)
9
+ remove_custom_properties!
10
+ add!(custom_attributes)
11
+ end
12
+
13
+ def add!(custom_attributes)
14
+ custom_attributes.each do |custom_attribute|
15
+ ::Fakecrm.logger.debug "adding custom attribute: #{custom_attribute.name} to #{self.resource.name}"
16
+ add_property!(custom_attribute)
17
+ end
18
+
19
+ # write state
20
+ return self.resource.auto_upgrade! unless custom_attributes.empty?
21
+ end
22
+
23
+ def remove_custom_properties!
24
+ self.resource.properties.each do |property|
25
+ self.resource.properties.delete(property) if property.name =~ /^custom_/
26
+ end
27
+ end
28
+
29
+ def add_property!(custom_attribute)
30
+ property_name = "custom_#{custom_attribute.name}".to_sym
31
+
32
+ # do not overwrite existing properties!
33
+ if self.resource.properties[property_name]
34
+ ::Fakecrm.logger.debug "adding custom attribute: #{custom_attribute.name} to #{self.resource.name}"
35
+ end
36
+
37
+ case custom_attribute.type
38
+ when "string"
39
+ self.resource.send(:property, property_name, ::DataMapper::Property::String, :length => custom_attribute.max_length.to_i)
40
+ when "text"
41
+ self.resource.send(:property, property_name, ::DataMapper::Property::Text)
42
+ when "enum"
43
+ self.resource.send(:property, property_name, ::DataMapper::Property::Enum, :flags => custom_attribute.valid_values)
44
+ when "multienum"
45
+ # FIXME: multienum should validate valid_values
46
+ self.resource.send(:property, property_name, ::DataMapper::Property::CommaSeparatedList)
47
+ end
48
+
49
+ # FIXME: validate mandatory fields
50
+ end
51
+
52
+ attr_accessor :resource
53
+ end
54
+ end
55
+
@@ -0,0 +1,30 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module Fakecrm
4
+ class Mailing
5
+ include DataMapper::Resource
6
+
7
+ property :id, Serial
8
+ property :title, String, :required => true
9
+ property :mailing_type, String, :required => true
10
+
11
+ property :body, Text
12
+ property :dtstart_at, DateTime
13
+ property :email_from, String
14
+ property :email_reply_to, String
15
+ property :email_subject, String
16
+ property :html_body, Text
17
+
18
+ property :released_at, DateTime
19
+ property :created_at, DateTime
20
+ property :changed_at, DateTime
21
+ property :updated_at, DateTime
22
+ property :deleted_at, ParanoidDateTime
23
+
24
+ property :updated_by, String, :default => 'root'
25
+ property :released_by, String, :default => 'root'
26
+
27
+ belongs_to :event, :required => false
28
+ end
29
+ end
30
+
@@ -0,0 +1,17 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/contact'
3
+
4
+ module Fakecrm
5
+ class Password
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+ property :token, String, :default => 'dead' * 10
10
+ property :password, String
11
+
12
+ validates_length_of :password, :min => 1, :unless => lambda { |p| p.password.nil? }
13
+
14
+ belongs_to :contact
15
+ end
16
+ end
17
+
@@ -0,0 +1,18 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Fakecrm
3
+ class Role
4
+ include DataMapper::Resource
5
+
6
+ property :id, String, :key => true # default will not work here
7
+ property :name, String, :required => true
8
+ property :description, String
9
+
10
+ property :permissions, CommaSeparatedList
11
+
12
+ def name=(new_name)
13
+ self.id = new_name if self.id.nil?
14
+ super
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,41 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Fakecrm
3
+ class Template
4
+ include DataMapper::Resource
5
+
6
+ property :id, Serial
7
+ property :body, Json, :default => {}
8
+
9
+ def templates
10
+ system_default.merge(body)
11
+ end
12
+
13
+ private
14
+
15
+ def system_default
16
+ {
17
+ "notification_email_to"=>"",
18
+ "notification_email_from"=>"",
19
+ "notification_email_reply_to"=>"",
20
+ "notification_email_bcc"=>"",
21
+ "notification_email_subject"=>"",
22
+ "notification_email_body"=>"",
23
+ "digest_email_from"=>"",
24
+ "digest_email_reply_to"=>"",
25
+ "digest_email_bcc"=>"",
26
+ "digest_email_subject"=>"",
27
+ "digest_email_body"=>"",
28
+ "password_request_email_from"=>"",
29
+ "password_request_email_reply_to"=>"",
30
+ "password_request_email_bcc"=>"",
31
+ "password_request_email_subject"=>"New Password Requested",
32
+ "password_request_email_body"=>
33
+ "To reset your password click the URL below:\r\n\r\n {{password_request_url}}\r\n\r\nIf you did not request your password to be reset please ignore this email and your password will stay as it is.",
34
+ "contact_salutation"=>
35
+ "{% assign anr = '' %} \r\n{% if contact.name_prefix contains 'Dr.' %} \r\n{% assign anr = 'Dr. ' %} \r\n{% endif %} \r\n{% if contact.name_prefix contains 'Prof.' %} \r\n{% assign anr = 'Prof. ' %} \r\n{% endif %} \r\n\r\n{% case contact.gender %} \r\n{% when \"M\" %} \r\nSehr geehrter Herr {{anr}}{{contact.last_name}}, \r\n{% when \"F\" %} \r\nSehr geehrte Frau {{anr}}{{contact.last_name}}, \r\n{% else %} \r\nSehr geehrte Damen und Herren, \r\n{% endcase %}"
36
+ }
37
+ end
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,90 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/custom_type'
3
+
4
+ module Fakecrm
5
+ class ResourceView
6
+ class << self
7
+ def decorate(source, options={})
8
+ if source.class.include?(::Enumerable)
9
+ source.map {|item| self.new(item, options)}
10
+ else
11
+ self.new(source, options)
12
+ end
13
+ end
14
+ end
15
+
16
+ def initialize(resource, options={})
17
+ self.resource = resource
18
+
19
+ self.custom_attributes = get_custom_attributes(self.resource)
20
+ self.properties = get_resource_properties(self.resource)
21
+
22
+ self.include = options.fetch(:include, :all)
23
+ self.exclude = options.fetch(:exclude, [])
24
+ self.additional = options.fetch(:methods, get_additional_methods(self.resource))
25
+ end
26
+
27
+
28
+ def to_json(*args)
29
+ return as_json.to_json
30
+ end
31
+
32
+ def as_json(*args)
33
+ result = {}
34
+
35
+ self.properties.each do |property|
36
+ if available?(property) && include?(property)
37
+ result[property] = resource.send(property)
38
+ end
39
+ end
40
+
41
+ self.additional.each do |method|
42
+ result[method] = resource.send(method)
43
+ end
44
+
45
+ return result
46
+ end
47
+
48
+ def available?(property)
49
+ if property =~ /^custom/
50
+ self.custom_attributes.include?(property)
51
+ else
52
+ true
53
+ end
54
+ end
55
+
56
+ def include?(property)
57
+ !self.exclude.include?(property) && (self.include == :all || self.include.include?(property))
58
+ end
59
+
60
+ def exclude?(property)
61
+ !include?(property)
62
+ end
63
+
64
+ def get_additional_methods(resource)
65
+ if resource.class.respond_to? :virtual_properties
66
+ resource.class.virtual_properties || []
67
+ else
68
+ []
69
+ end
70
+ end
71
+
72
+ def get_resource_properties(resource)
73
+ resource.class.properties.map(&:name)
74
+ end
75
+
76
+ def get_custom_attributes(resource)
77
+ if resource.respond_to?(:one_of_a_kind?) && resource.one_of_a_kind?
78
+ CustomType.get!(resource.kind).custom_attributes.map(&:name).map(&:to_sym)
79
+ else
80
+ get_resource_properties(resource).select {|property| property =~ /^custom/ }
81
+ end
82
+ end
83
+
84
+ protected
85
+ attr_accessor :properties, :resource, :custom_attributes
86
+ attr_accessor :include, :exclude, :additional
87
+
88
+ end
89
+ end
90
+
@@ -0,0 +1,11 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/account'
3
+ require 'fakecrm/resource/activity'
4
+ require 'fakecrm/resource/contact'
5
+ require 'fakecrm/resource/custom_type'
6
+ require 'fakecrm/resource/event'
7
+ require 'fakecrm/resource/mailing'
8
+ require 'fakecrm/resource/password'
9
+ require 'fakecrm/resource/role'
10
+ require 'fakecrm/resource/template'
11
+