fakecrm 0.9.9.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|