infopark_webcrm_sdk 1.0.0.rc3
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/LICENSE +840 -0
- data/README.md +113 -0
- data/UPGRADE.md +507 -0
- data/config/ca-bundle.crt +4484 -0
- data/lib/crm/account.rb +17 -0
- data/lib/crm/activity.rb +143 -0
- data/lib/crm/collection.rb +41 -0
- data/lib/crm/contact.rb +121 -0
- data/lib/crm/core/attachment_store.rb +122 -0
- data/lib/crm/core/basic_resource.rb +68 -0
- data/lib/crm/core/configuration.rb +65 -0
- data/lib/crm/core/connection_manager.rb +98 -0
- data/lib/crm/core/item_enumerator.rb +61 -0
- data/lib/crm/core/log_subscriber.rb +41 -0
- data/lib/crm/core/mixins/attribute_provider.rb +135 -0
- data/lib/crm/core/mixins/change_loggable.rb +98 -0
- data/lib/crm/core/mixins/findable.rb +28 -0
- data/lib/crm/core/mixins/inspectable.rb +27 -0
- data/lib/crm/core/mixins/merge_and_deletable.rb +17 -0
- data/lib/crm/core/mixins/modifiable.rb +102 -0
- data/lib/crm/core/mixins/searchable.rb +88 -0
- data/lib/crm/core/mixins.rb +6 -0
- data/lib/crm/core/rest_api.rb +148 -0
- data/lib/crm/core/search_configurator.rb +207 -0
- data/lib/crm/core.rb +6 -0
- data/lib/crm/errors.rb +169 -0
- data/lib/crm/event.rb +17 -0
- data/lib/crm/event_contact.rb +16 -0
- data/lib/crm/mailing.rb +111 -0
- data/lib/crm/template_set.rb +81 -0
- data/lib/crm/type.rb +78 -0
- data/lib/crm.rb +154 -0
- data/lib/infopark_webcrm_sdk.rb +1 -0
- metadata +149 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
module Crm; module Core
|
2
|
+
# +ItemEnumerator+ provides methods for accessing items identified by their ID.
|
3
|
+
# It implements {#each} and includes the
|
4
|
+
# {http://ruby-doc.org/core/Enumerable.html Enumerable} mixin,
|
5
|
+
# which provides methods such as +#map+, +#select+ or +#take+.
|
6
|
+
# @api public
|
7
|
+
class ItemEnumerator
|
8
|
+
include Enumerable
|
9
|
+
include Core::Mixins::Inspectable
|
10
|
+
inspectable :length, :total
|
11
|
+
|
12
|
+
# Returns the IDs of the items to enumerate.
|
13
|
+
# @return [Array<String>]
|
14
|
+
# @api public
|
15
|
+
attr_reader :ids
|
16
|
+
|
17
|
+
# If the ItemEnumerator is the result of a search, it returns the total number of search hits.
|
18
|
+
# Otherwise, it returns {#length}.
|
19
|
+
# @return [Fixnum]
|
20
|
+
# @api public
|
21
|
+
attr_reader :total
|
22
|
+
|
23
|
+
def initialize(ids, total: nil)
|
24
|
+
@ids = ids
|
25
|
+
@total = total || ids.length
|
26
|
+
end
|
27
|
+
|
28
|
+
# Iterates over the {#ids} and fetches the corresponding items on demand.
|
29
|
+
# @overload each
|
30
|
+
# Calls the block once for each item, passing this item as a parameter.
|
31
|
+
# @yieldparam item [BasicResource]
|
32
|
+
# @return [void]
|
33
|
+
# @overload each
|
34
|
+
# If no block is given, an {http://ruby-doc.org/core/Enumerator.html enumerator}
|
35
|
+
# is returned instead.
|
36
|
+
# @return [Enumerator<BasicResource>]
|
37
|
+
# @raise [Errors::ResourceNotFound] if at least one of the IDs could not be found.
|
38
|
+
# @api public
|
39
|
+
def each(&block)
|
40
|
+
return enum_for(:each) unless block_given?
|
41
|
+
|
42
|
+
server_limit = 100
|
43
|
+
@ids.each_slice(server_limit) do |sliced_ids|
|
44
|
+
RestApi.instance.get('mget', {'ids' => sliced_ids}).map do |item|
|
45
|
+
block.call "Crm::#{item['base_type']}".constantize.new(item)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the number of items.
|
51
|
+
# Prefer this method over +Enumerable#count+
|
52
|
+
# because +#length+ doesn't fetch the items and therefore is faster than +Enumerable#count+.
|
53
|
+
# @return [Fixnum]
|
54
|
+
# @api public
|
55
|
+
def length
|
56
|
+
@ids.length
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :size, :length
|
60
|
+
end
|
61
|
+
end; end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'action_dispatch'
|
2
|
+
|
3
|
+
module Crm; module Core
|
4
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
5
|
+
def logger
|
6
|
+
self.class.logger.presence or super
|
7
|
+
end
|
8
|
+
|
9
|
+
def request(event)
|
10
|
+
info { "#{event.payload[:method].to_s.upcase} #{event.payload[:resource_path]}" }
|
11
|
+
request_payload = event.payload[:request_payload]
|
12
|
+
if request_payload.present?
|
13
|
+
debug { " request body: #{parameter_filter.filter(request_payload)}" }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def response(event)
|
18
|
+
r = event.payload[:response]
|
19
|
+
info {
|
20
|
+
" #{r.code} #{r.message} #{r.body.to_s.length} (total: #{event.duration.round(1)}ms)"
|
21
|
+
}
|
22
|
+
debug {
|
23
|
+
response_payload = MultiJson.load(r.body)
|
24
|
+
" response body: #{parameter_filter.filter(response_payload)}"
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def establish_connection(event)
|
29
|
+
debug {
|
30
|
+
attempt = event.payload[:attempt]
|
31
|
+
" Establishing connection on attempt #{attempt} (#{event.duration.round(1)}ms)"
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def parameter_filter
|
38
|
+
@parameter_filter ||= ::ActionDispatch::Http::ParameterFilter.new(['password'])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end; end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module Crm; module Core; module Mixins
|
2
|
+
# +AttributeProvider+ provides multiple ways to access the attributes of an item.
|
3
|
+
# All attributes are available using {#[]}, {#attributes}
|
4
|
+
# or a method named like the attribute.
|
5
|
+
# @example
|
6
|
+
# contact
|
7
|
+
# # => Crm::Contact
|
8
|
+
#
|
9
|
+
# contact.first_name
|
10
|
+
# # => "John"
|
11
|
+
#
|
12
|
+
# contact['first_name']
|
13
|
+
# # => "John"
|
14
|
+
#
|
15
|
+
# contact[:first_name]
|
16
|
+
# # => "John"
|
17
|
+
#
|
18
|
+
# contact.unknown_attribute
|
19
|
+
# # => raises NoMethodError
|
20
|
+
#
|
21
|
+
# contact['unknown_attribute']
|
22
|
+
# # => nil
|
23
|
+
#
|
24
|
+
# contact.attributes
|
25
|
+
# # => {
|
26
|
+
# # ...
|
27
|
+
# # 'first_name' => 'John',
|
28
|
+
# # ...
|
29
|
+
# # }
|
30
|
+
# @api public
|
31
|
+
module AttributeProvider
|
32
|
+
def initialize(attributes = nil)
|
33
|
+
load_attributes(attributes || {})
|
34
|
+
|
35
|
+
super()
|
36
|
+
end
|
37
|
+
|
38
|
+
# Makes all attributes accessible as methods.
|
39
|
+
def method_missing(method_name, *args)
|
40
|
+
return self[method_name] if has_attribute?(method_name)
|
41
|
+
[
|
42
|
+
"#{method_name}_id",
|
43
|
+
"#{method_name.to_s.singularize}_ids",
|
44
|
+
].each do |id_name|
|
45
|
+
return Crm.find(self[id_name]) if has_attribute?(id_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
# Motivation see http://blog.marc-andre.ca/2010/11/15/methodmissing-politely/
|
52
|
+
def respond_to_missing?(method_name, *)
|
53
|
+
return true if has_attribute?(method_name)
|
54
|
+
return true if has_attribute?("#{method_name}_id")
|
55
|
+
return true if has_attribute?("#{method_name.to_s.singularize}_ids")
|
56
|
+
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
def methods(*args)
|
61
|
+
super | @extra_methods
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the value associated with +attribute_name+.
|
65
|
+
# Returns +nil+ if not found.
|
66
|
+
# @example
|
67
|
+
# contact['first_name']
|
68
|
+
# # => "John"
|
69
|
+
#
|
70
|
+
# contact[:first_name]
|
71
|
+
# # => "John"
|
72
|
+
#
|
73
|
+
# contact['nonexistent']
|
74
|
+
# # => nil
|
75
|
+
# @param attribute_name [String, Symbol]
|
76
|
+
# @return [Object, nil]
|
77
|
+
# @api public
|
78
|
+
def [](attribute_name)
|
79
|
+
@attrs[attribute_name.to_s]
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the hash of all attribute names and their values.
|
83
|
+
# @return [HashWithIndifferentAccess]
|
84
|
+
# @api public
|
85
|
+
def attributes
|
86
|
+
@attrs
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns the value before type cast.
|
90
|
+
# Returns +nil+ if attribute_name not found.
|
91
|
+
# @example
|
92
|
+
# contact[:created_at]
|
93
|
+
# # => 2012-05-07 17:15:00 +0200
|
94
|
+
#
|
95
|
+
# contact.raw(:created_at)
|
96
|
+
# # => "2012-05-07T15:15:00+00:00"
|
97
|
+
# @return [Object, nil]
|
98
|
+
# @api public
|
99
|
+
def raw(attribute_name)
|
100
|
+
@raw_attrs[attribute_name] || @attrs[attribute_name]
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def load_attributes(attributes)
|
106
|
+
@raw_attrs = HashWithIndifferentAccess.new
|
107
|
+
@attrs = attributes.each_with_object(HashWithIndifferentAccess.new) do |(key, value), hash|
|
108
|
+
if key.ends_with?('_at')
|
109
|
+
@raw_attrs[key] = value
|
110
|
+
value = begin
|
111
|
+
Time.parse(value.to_s).in_time_zone
|
112
|
+
rescue ArgumentError
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
hash[key] = value
|
117
|
+
end
|
118
|
+
@extra_methods = []
|
119
|
+
@attrs.keys.each do |key|
|
120
|
+
key = key.to_s
|
121
|
+
@extra_methods << key.to_sym
|
122
|
+
@extra_methods << key.gsub(/_id$/, '').to_sym if key.ends_with?('_id')
|
123
|
+
@extra_methods << key.gsub(/_ids$/, '').pluralize.to_sym if key.ends_with?('_ids')
|
124
|
+
end
|
125
|
+
@attrs.freeze
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def has_attribute?(attribute_name)
|
132
|
+
@attrs.has_key?(attribute_name.to_s)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end; end; end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Crm; module Core; module Mixins
|
2
|
+
# +ChangeLoggable+ provides access to the change log of a resource.
|
3
|
+
# A {ChangeLoggable::Change change log entry} contains the +before+ and +after+ values
|
4
|
+
# of all attributes that were changed by an update.
|
5
|
+
# It also includes the author (+changed_by+) and the timestamp (+changed_at+) of the change.
|
6
|
+
# @example
|
7
|
+
# contact
|
8
|
+
# # => Crm::Contact
|
9
|
+
#
|
10
|
+
# changes = contact.changes
|
11
|
+
# # => Array<ChangeLoggable::Change>
|
12
|
+
#
|
13
|
+
# change = changes.first
|
14
|
+
# # => ChangeLoggable::Change
|
15
|
+
#
|
16
|
+
# change.changed_by
|
17
|
+
# # => 'john_smith'
|
18
|
+
#
|
19
|
+
# change.changed_at
|
20
|
+
# # => Time
|
21
|
+
#
|
22
|
+
# change.details.keys
|
23
|
+
# # => ['email', 'locality']
|
24
|
+
#
|
25
|
+
# detail = change.details[:email]
|
26
|
+
# # => ChangeLoggable::Change::Detail
|
27
|
+
#
|
28
|
+
# detail.before
|
29
|
+
# # => old@example.com
|
30
|
+
#
|
31
|
+
# detail.after
|
32
|
+
# # => new@example.com
|
33
|
+
# @api public
|
34
|
+
module ChangeLoggable
|
35
|
+
# +Change+ represents a single change log entry contained in
|
36
|
+
# {ChangeLoggable#changes item.changes}.
|
37
|
+
# See {Crm::Core::Mixins::ChangeLoggable ChangeLoggable} for details.
|
38
|
+
# @api public
|
39
|
+
class Change
|
40
|
+
include Core::Mixins::AttributeProvider
|
41
|
+
|
42
|
+
def initialize(raw_change)
|
43
|
+
change = raw_change.dup
|
44
|
+
change['details'] = change['details'].each_with_object({}) do |(attr_name, detail), hash|
|
45
|
+
hash[attr_name] = Detail.new(detail)
|
46
|
+
end
|
47
|
+
super(change)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @!attribute [r] changed_at
|
51
|
+
# Returns the timestamp of the change to the item.
|
52
|
+
# @return [Time]
|
53
|
+
# @api public
|
54
|
+
|
55
|
+
# @!attribute [r] changed_by
|
56
|
+
# Returns the login of the API user who made the change.
|
57
|
+
# @return [String]
|
58
|
+
# @api public
|
59
|
+
|
60
|
+
# @!attribute [r] details
|
61
|
+
# Returns the details of the change
|
62
|
+
# (i.e. +before+ and +after+ of every changed attribute)
|
63
|
+
# @return [Array<Detail>]
|
64
|
+
# @api public
|
65
|
+
|
66
|
+
# +Detail+ represents a single detail of a
|
67
|
+
# {Crm::Core::Mixins::ChangeLoggable::Change change},
|
68
|
+
# which can be accessed by means of {Change#details change.details}.
|
69
|
+
# See {Crm::Core::Mixins::ChangeLoggable ChangeLoggable} for details.
|
70
|
+
# @api public
|
71
|
+
class Detail
|
72
|
+
# @!attribute [r] before
|
73
|
+
# Returns the value before the change.
|
74
|
+
# @return [Object]
|
75
|
+
# @api public
|
76
|
+
|
77
|
+
# @!attribute [r] after
|
78
|
+
# Returns the value after the change.
|
79
|
+
# @return [Object]
|
80
|
+
# @api public
|
81
|
+
|
82
|
+
# flush yardoc!!!!
|
83
|
+
include Core::Mixins::AttributeProvider
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns the most recent changes made to this item.
|
88
|
+
# @param limit [Fixnum] the number of changes to return at most.
|
89
|
+
# Maximum: +100+. Default: +10+.
|
90
|
+
# @return [Array<Change>]
|
91
|
+
# @api public
|
92
|
+
def changes(limit: 10)
|
93
|
+
RestApi.instance.get("#{path}/changes", {"limit" => limit})['results'].map do |change|
|
94
|
+
Change.new(change)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end; end; end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Crm; module Core; module Mixins
|
2
|
+
# +Findable+ lets you fetch an item using {ClassMethods#find .find}.
|
3
|
+
# @example
|
4
|
+
# Crm::Contact.find('e70a7123f499c5e0e9972ab4dbfb8fe3')
|
5
|
+
# # => Crm::Contact
|
6
|
+
# @api public
|
7
|
+
module Findable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# @api public
|
11
|
+
module ClassMethods
|
12
|
+
# Returns the requested item.
|
13
|
+
# @param id [String] the ID of the item.
|
14
|
+
# @return [BasicResource]
|
15
|
+
# @raise [Errors::ResourceNotFound]
|
16
|
+
# if the ID could not be found or the base type did not match.
|
17
|
+
# @api public
|
18
|
+
def find(id)
|
19
|
+
if id.blank?
|
20
|
+
raise Crm::Errors::ResourceNotFound.new(
|
21
|
+
"Items could not be found.", [id])
|
22
|
+
end
|
23
|
+
new({'id' => id}).reload
|
24
|
+
end
|
25
|
+
end
|
26
|
+
# @!parse extend ClassMethods
|
27
|
+
end
|
28
|
+
end; end; end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Crm; module Core; module Mixins
|
2
|
+
module Inspectable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def inspect
|
6
|
+
field_values = self.class.inspectable_fields.map do |field|
|
7
|
+
value = self.send(field).inspect
|
8
|
+
|
9
|
+
"#{field}=#{value}"
|
10
|
+
end
|
11
|
+
|
12
|
+
"#<#{self.class.name} #{field_values.join(', ')}>"
|
13
|
+
end
|
14
|
+
|
15
|
+
included do
|
16
|
+
cattr_accessor :inspectable_fields
|
17
|
+
|
18
|
+
self.inspectable_fields = []
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def inspectable(*fields)
|
23
|
+
self.inspectable_fields = *fields
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end; end; end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Crm; module Core; module Mixins
|
2
|
+
# +MergeAndDeletable+ provides the common {#merge_and_delete} method
|
3
|
+
# for {Account accounts} and {Contact contacts}.
|
4
|
+
# @api public
|
5
|
+
module MergeAndDeletable
|
6
|
+
# Assigns the items associated with this item to the account or contact
|
7
|
+
# whose ID is +merge_into_id+. Afterwards, the current item is deleted.
|
8
|
+
# @param merge_into_id [String]
|
9
|
+
# the ID of the account or contact to which the associated items are assigned.
|
10
|
+
# @return [self] the deleted item.
|
11
|
+
# @api public
|
12
|
+
def merge_and_delete(merge_into_id)
|
13
|
+
load_attributes(
|
14
|
+
RestApi.instance.post("#{path}/merge_and_delete", {"merge_into_id" => merge_into_id}))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end; end; end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
|
3
|
+
module Crm; module Core; module Mixins
|
4
|
+
# +Modifiable+ is a collection of methods that are used to {ClassMethods#create .create},
|
5
|
+
# {#update}, {#delete}, and {#undelete} an Infopark WebCRM item.
|
6
|
+
# @api public
|
7
|
+
module Modifiable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# @api public
|
11
|
+
module ClassMethods
|
12
|
+
# Creates a new item using the given +attributes+.
|
13
|
+
# @example
|
14
|
+
# Crm::Contact.create({
|
15
|
+
# language: 'en',
|
16
|
+
# last_name: 'Smith',
|
17
|
+
# })
|
18
|
+
# # => Crm::Contact
|
19
|
+
# @param attributes [Hash{String, Symbol => String}] the attributes of the new item.
|
20
|
+
# @return [BasicResource] the created item.
|
21
|
+
# @raise [Errors::InvalidKeys] if +attributes+ contains unknown attribute names.
|
22
|
+
# @raise [Errors::InvalidValues] if +attributes+ contains incorrect values.
|
23
|
+
# @api public
|
24
|
+
def create(attributes = {})
|
25
|
+
new(RestApi.instance.post(path, attributes))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
# @!parse extend ClassMethods
|
29
|
+
|
30
|
+
# Updates the attributes of this item.
|
31
|
+
# @example
|
32
|
+
# contact.last_name
|
33
|
+
# # => 'Smith'
|
34
|
+
#
|
35
|
+
# contact.locality
|
36
|
+
# # => 'New York'
|
37
|
+
#
|
38
|
+
# contact.update({locality: 'Boston'})
|
39
|
+
# # => Crm::Contact
|
40
|
+
#
|
41
|
+
# contact.last_name
|
42
|
+
# # => 'Smith'
|
43
|
+
#
|
44
|
+
# contact.locality
|
45
|
+
# # => 'Boston'
|
46
|
+
# @param attributes [Hash{String, Symbol => String}] the new attributes.
|
47
|
+
# @return [self] the updated item.
|
48
|
+
# @raise [Errors::InvalidKeys] if +attributes+ contains unknown attribute names.
|
49
|
+
# @raise [Errors::InvalidValues] if +attributes+ contains incorrect values.
|
50
|
+
# @raise [Errors::ResourceConflict] if the item has been changed concurrently.
|
51
|
+
# {Core::BasicResource#reload Reload} it, review the changes and retry.
|
52
|
+
# @api public
|
53
|
+
def update(attributes = {})
|
54
|
+
load_attributes(RestApi.instance.put(path, attributes, if_match_header))
|
55
|
+
end
|
56
|
+
|
57
|
+
# Soft-deletes this item (i.e. marks it as deleted).
|
58
|
+
#
|
59
|
+
# The deleted item can be {#undelete undeleted}.
|
60
|
+
# @example
|
61
|
+
# contact.deleted?
|
62
|
+
# # => false
|
63
|
+
#
|
64
|
+
# contact.delete
|
65
|
+
# # => Crm::Contact
|
66
|
+
#
|
67
|
+
# contact.deleted?
|
68
|
+
# # => true
|
69
|
+
# @return [self] the deleted item.
|
70
|
+
# @raise [Errors::ResourceConflict] if the item has been changed concurrently.
|
71
|
+
# {Core::BasicResource#reload Reload} it, review the changes and retry.
|
72
|
+
# @api public
|
73
|
+
def delete
|
74
|
+
load_attributes(RestApi.instance.delete(path, nil, if_match_header))
|
75
|
+
end
|
76
|
+
|
77
|
+
# Undeletes this deleted item.
|
78
|
+
# @example
|
79
|
+
# contact.deleted?
|
80
|
+
# # => true
|
81
|
+
#
|
82
|
+
# contact.undelete
|
83
|
+
# # => Crm::Contact
|
84
|
+
#
|
85
|
+
# contact.deleted?
|
86
|
+
# # => false
|
87
|
+
# @return [self] the undeleted item.
|
88
|
+
# @api public
|
89
|
+
def undelete
|
90
|
+
load_attributes(RestApi.instance.put("#{path}/undelete", {}))
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns +true+ if the item was deleted (i.e. +item.deleted_at+ is not empty).
|
94
|
+
# @return [Boolean]
|
95
|
+
# @api public
|
96
|
+
def deleted?
|
97
|
+
self['deleted_at'].present?
|
98
|
+
end
|
99
|
+
|
100
|
+
alias_method :destroy, :delete
|
101
|
+
end
|
102
|
+
end; end; end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Crm; module Core; module Mixins
|
2
|
+
# +Searchable+ provides several methods related to searching.
|
3
|
+
# @api public
|
4
|
+
module Searchable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
# @api public
|
8
|
+
module ClassMethods
|
9
|
+
# Returns the item of this base type that was created first.
|
10
|
+
# @return [BasicResource]
|
11
|
+
# @api public
|
12
|
+
def first
|
13
|
+
search_configurator.
|
14
|
+
sort_by('created_at').
|
15
|
+
limit(1).
|
16
|
+
perform_search.
|
17
|
+
first
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns an {Crm::Core::ItemEnumerator enumerator} for iterating over all items
|
21
|
+
# of this base type. The items are sorted by +created_at+.
|
22
|
+
# @param include_deleted [Boolean] whether to include deleted items. Default: +false+.
|
23
|
+
# @return [ItemEnumerator]
|
24
|
+
# @api public
|
25
|
+
def all(include_deleted: false)
|
26
|
+
search_configurator.
|
27
|
+
sort_by('created_at').
|
28
|
+
unlimited.
|
29
|
+
include_deleted(include_deleted).
|
30
|
+
perform_search
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a new {Crm::Core::SearchConfigurator SearchConfigurator} set to the given
|
34
|
+
# filter (+field+, +condition+, +value+). Additionally, it is limited
|
35
|
+
# to this base type and can be further refined using chainable methods.
|
36
|
+
# This method is equivalent to +search_configurator.and(field, condition, value)+.
|
37
|
+
# See {SearchConfigurator#and} for parameters and examples.
|
38
|
+
# @return [SearchConfigurator]
|
39
|
+
# @api public
|
40
|
+
def where(field, condition, value = nil)
|
41
|
+
search_configurator.and(field, condition, value)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns a new {Crm::Core::SearchConfigurator SearchConfigurator} set to the given
|
45
|
+
# negated filter (+field+, +condition+, +value+). Additionally, it is limited
|
46
|
+
# to this base type and can be further refined using chainable methods.
|
47
|
+
# This method is equivalent to +search_configurator.and_not(field, condition, value)+.
|
48
|
+
# See {SearchConfigurator#and_not} for parameters and examples.
|
49
|
+
# @return [SearchConfigurator]
|
50
|
+
# @api public
|
51
|
+
def where_not(field, condition, value = nil)
|
52
|
+
search_configurator.and_not(field, condition, value)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns a new {Crm::Core::SearchConfigurator SearchConfigurator} set to the given
|
56
|
+
# +query+. Additionally, it is limited
|
57
|
+
# to this base type and can be further refined using chainable methods.
|
58
|
+
# This method is equivalent to +search_configurator.query(query)+.
|
59
|
+
# See {SearchConfigurator#query} for examples.
|
60
|
+
# @return [SearchConfigurator]
|
61
|
+
# @api public
|
62
|
+
def query(query)
|
63
|
+
search_configurator.query(query)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns a new {Crm::Core::SearchConfigurator SearchConfigurator} limited
|
67
|
+
# to this base type. It can be further refined using chainable methods.
|
68
|
+
# @return [SearchConfigurator]
|
69
|
+
# @api public
|
70
|
+
def search_configurator
|
71
|
+
SearchConfigurator.new({
|
72
|
+
filters: filters_for_base_type,
|
73
|
+
})
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def filters_for_base_type
|
79
|
+
[{
|
80
|
+
field: 'base_type',
|
81
|
+
condition: 'equals',
|
82
|
+
value: base_type,
|
83
|
+
}]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
# @!parse extend ClassMethods
|
87
|
+
end
|
88
|
+
end; end; end
|