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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/Rakefile +113 -0
- data/bin/fakecrm +37 -0
- data/fakecrm.gemspec +34 -0
- data/lib/fakecrm/application.rb +85 -0
- data/lib/fakecrm/configuration.rb +8 -0
- data/lib/fakecrm/drop.rb +59 -0
- data/lib/fakecrm/embedded.rb +32 -0
- data/lib/fakecrm/fetch.rb +139 -0
- data/lib/fakecrm/initialize.rb +16 -0
- data/lib/fakecrm/localized_dm.rb +12 -0
- data/lib/fakecrm/resource/account.rb +33 -0
- data/lib/fakecrm/resource/activity.rb +57 -0
- data/lib/fakecrm/resource/contact.rb +51 -0
- data/lib/fakecrm/resource/custom_attribute.rb +20 -0
- data/lib/fakecrm/resource/custom_type.rb +96 -0
- data/lib/fakecrm/resource/event.rb +52 -0
- data/lib/fakecrm/resource/event_contact.rb +21 -0
- data/lib/fakecrm/resource/extensions/kinds.rb +26 -0
- data/lib/fakecrm/resource/extensions/type_extender.rb +42 -0
- data/lib/fakecrm/resource/extensions/type_extension.rb +55 -0
- data/lib/fakecrm/resource/mailing.rb +30 -0
- data/lib/fakecrm/resource/password.rb +17 -0
- data/lib/fakecrm/resource/role.rb +18 -0
- data/lib/fakecrm/resource/template.rb +41 -0
- data/lib/fakecrm/resource/views/resource_view.rb +90 -0
- data/lib/fakecrm/resources.rb +11 -0
- data/lib/fakecrm/server/accounts.rb +39 -0
- data/lib/fakecrm/server/activities.rb +39 -0
- data/lib/fakecrm/server/contacts.rb +118 -0
- data/lib/fakecrm/server/custom_types.rb +34 -0
- data/lib/fakecrm/server/event_contacts.rb +38 -0
- data/lib/fakecrm/server/events.rb +47 -0
- data/lib/fakecrm/server/mailings.rb +44 -0
- data/lib/fakecrm/server/roles.rb +44 -0
- data/lib/fakecrm/server/templates.rb +24 -0
- data/lib/fakecrm/server.rb +37 -0
- data/lib/fakecrm/version.rb +5 -0
- data/lib/fakecrm.rb +36 -0
- data/locales/de.yml +25 -0
- data/locales/en.yml +25 -0
- data/test/embedded/.gitignore +15 -0
- data/test/embedded/Gemfile +6 -0
- data/test/embedded/Rakefile +7 -0
- data/test/embedded/app/models/.gitkeep +0 -0
- data/test/embedded/config/application.rb +44 -0
- data/test/embedded/config/boot.rb +6 -0
- data/test/embedded/config/environment.rb +5 -0
- data/test/embedded/config/environments/development.rb +20 -0
- data/test/embedded/config/environments/test.rb +21 -0
- data/test/embedded/config/initializers/fakecrm.rb +8 -0
- data/test/embedded/config/initializers/secret_token.rb +7 -0
- data/test/embedded/config/initializers/session_store.rb +8 -0
- data/test/embedded/config/initializers/wrap_parameters.rb +14 -0
- data/test/embedded/config/locales/en.yml +5 -0
- data/test/embedded/config/routes.rb +2 -0
- data/test/embedded/config.ru +4 -0
- data/test/embedded/lib/assets/.gitkeep +0 -0
- data/test/embedded/lib/tasks/.gitkeep +0 -0
- data/test/embedded/log/.gitkeep +0 -0
- data/test/embedded/script/rails +6 -0
- 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
|
+
|