dynamics_crm 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98498eb29f5847c9e344859c2a728367d4e5227a
4
- data.tar.gz: a6621ceb97f27de1298c7afba4b99cfd6f5fa44b
3
+ metadata.gz: f9b5b7d4367ee302f2a1e925b08b24f946c5c778
4
+ data.tar.gz: 105acef89d7636ed35fefecbf5e775f1d81f42d6
5
5
  SHA512:
6
- metadata.gz: 1773ffbe9669459911e9c08bc44f241fa825ca14858f738084e7179cb5b46b965b8c01222c3c6c0b98651da0da0dbdd3f59d52c4cfe304197950e9473379b666
7
- data.tar.gz: 261c9ae185cfdd0151ff118a56f78bb873ca69ef866dfbee46b9bc4e85265292c1cd1d5dad7ef1b18c143668fb9798938bf90089d92cb4dae3bb37d7a071e4a9
6
+ metadata.gz: 21555819445cc0def2c009775539fa497f927d81f635d57aa1b0a3f40a38cd344ca1b81fcbfb930e758d08689455c9f16b8ed4c58c200bbbebbac636ebd5de98
7
+ data.tar.gz: a7f4ed37563e4eae82536c63e4770820621d91bc520b8bbbddf3381db3cac92303a99b20ba2c4ed4208e14f9a0e6dfcc781dbca5fd6d7da33bca97ac0b117366
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.9.0 (March 13, 2017)
2
+ * Adds Filters support to Query Criteria #60
3
+ * Improve GUID attribute regex.
4
+ * Fix logging for non-200 response codes.
5
+
1
6
  ## 0.8.0 (January 4, 2017)
2
7
  * Support ArrayOfEntity so one can create bound entities like ActivityParties on create #41
3
8
  * Add special case for nil value #43
data/README.md CHANGED
@@ -70,6 +70,32 @@ while result.MoreRecords
70
70
  end
71
71
  ```
72
72
 
73
+ ### retrieve_multiple using complex Filters
74
+
75
+ ```ruby
76
+ # Build QueryExpression
77
+ query = DynamicsCRM::XML::QueryExpression.new('account')
78
+ query.columns = %w(accountid name telephone1)
79
+ # Switch to Or criteria
80
+ query.criteria.filter_operator = 'Or'
81
+
82
+ filter1 = DynamicsCRM::XML::FilterExpression.new('And')
83
+ filter1.add_condition('name', 'Equal', 'Integration Specialists')
84
+ filter1.add_condition('telephone1', 'In', ['(317) 845-2212', '3178452212'])
85
+
86
+ filter2 = DynamicsCRM::XML::FilterExpression.new('And')
87
+ filter2.add_condition('name', 'Equal', 'Thematics Development Inc.')
88
+ filter2.add_condition('telephone1', 'Null')
89
+
90
+ # Add Filters to criteria
91
+ query.criteria.add_filter(filter1)
92
+ query.criteria.add_filter(filter2)
93
+
94
+
95
+ result = client.retrieve_multiple(query)
96
+ ```
97
+
98
+
73
99
  ### fetch (FetchXml)
74
100
 
75
101
  ```ruby
data/lib/dynamics_crm.rb CHANGED
@@ -8,6 +8,7 @@ require "dynamics_crm/xml/condition_expression"
8
8
  require "dynamics_crm/xml/column_set"
9
9
  require "dynamics_crm/xml/criteria"
10
10
  require "dynamics_crm/xml/query_expression"
11
+ require "dynamics_crm/xml/filter_expression"
11
12
  require "dynamics_crm/xml/fetch_expression"
12
13
  require "dynamics_crm/xml/entity"
13
14
  require "dynamics_crm/xml/entity_reference"
@@ -64,7 +64,6 @@ module DynamicsCRM
64
64
  #
65
65
  # Returns true on success or raises Fault
66
66
  def authenticate(username, password)
67
-
68
67
  @username = username
69
68
  @password = password
70
69
 
@@ -108,37 +107,34 @@ module DynamicsCRM
108
107
  end
109
108
  end
110
109
 
111
-
112
110
  true
113
111
  end
114
112
 
115
113
  # These are all the operations defined by the Dynamics WSDL.
116
114
  # Tag names are case-sensitive.
117
115
  def create(entity_name, attributes)
118
-
119
116
  entity = XML::Entity.new(entity_name)
120
117
  entity.attributes = XML::Attributes.new(attributes)
121
118
 
122
119
  xml_response = post(organization_endpoint, create_request(entity))
123
- return Response::CreateResult.new(xml_response)
120
+ Response::CreateResult.new(xml_response)
124
121
  end
125
122
 
126
123
  # http://crmtroubleshoot.blogspot.com.au/2013/07/dynamics-crm-2011-php-and-soap-calls.html
127
124
  def retrieve(entity_name, guid, columns=[])
128
-
129
125
  column_set = XML::ColumnSet.new(columns)
130
126
  request = retrieve_request(entity_name, guid, column_set)
131
127
 
132
128
  xml_response = post(organization_endpoint, request)
133
- return Response::RetrieveResult.new(xml_response)
129
+ Response::RetrieveResult.new(xml_response)
134
130
  end
135
131
 
136
132
  def rollup(target_entity, query, rollup_type="Related")
137
- self.execute("Rollup", {
138
- Target: target_entity,
139
- Query: query,
140
- RollupType: rollup_type
141
- })
133
+ self.execute("Rollup", {
134
+ Target: target_entity,
135
+ Query: query,
136
+ RollupType: rollup_type
137
+ })
142
138
  end
143
139
 
144
140
  # Suports parameter list or QueryExpression object.
@@ -172,14 +168,14 @@ module DynamicsCRM
172
168
 
173
169
  request = update_request(entity)
174
170
  xml_response = post(organization_endpoint, request)
175
- return Response::UpdateResponse.new(xml_response)
171
+ Response::UpdateResponse.new(xml_response)
176
172
  end
177
173
 
178
174
  def delete(entity_name, guid)
179
175
  request = delete_request(entity_name, guid)
180
176
 
181
177
  xml_response = post(organization_endpoint, request)
182
- return Response::DeleteResponse.new(xml_response)
178
+ Response::DeleteResponse.new(xml_response)
183
179
  end
184
180
 
185
181
  def execute(action, parameters={}, response_class=nil)
@@ -187,19 +183,19 @@ module DynamicsCRM
187
183
  xml_response = post(organization_endpoint, request)
188
184
 
189
185
  response_class ||= Response::ExecuteResult
190
- return response_class.new(xml_response)
186
+ response_class.new(xml_response)
191
187
  end
192
188
 
193
189
  def associate(entity_name, guid, relationship, related_entities)
194
190
  request = associate_request(entity_name, guid, relationship, related_entities)
195
191
  xml_response = post(organization_endpoint, request)
196
- return Response::AssociateResponse.new(xml_response)
192
+ Response::AssociateResponse.new(xml_response)
197
193
  end
198
194
 
199
195
  def disassociate(entity_name, guid, relationship, related_entities)
200
196
  request = disassociate_request(entity_name, guid, relationship, related_entities)
201
197
  xml_response = post(organization_endpoint, request)
202
- return Response::DisassociateResponse.new(xml_response)
198
+ Response::DisassociateResponse.new(xml_response)
203
199
  end
204
200
 
205
201
  def create_attachment(entity_name, entity_id, options={})
@@ -324,28 +320,23 @@ module DynamicsCRM
324
320
  end
325
321
 
326
322
  def post(url, request)
327
- log_xml("REQUEST", request)
323
+ log_xml('REQUEST', request)
328
324
  uri = URI.parse(url)
329
325
 
330
326
  http = Net::HTTP.new uri.host, uri.port
331
327
  http.use_ssl = true
332
328
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
333
329
 
334
- req = Net::HTTP::Post.new(uri.request_uri, {
335
- "Connection" => "Keep-Alive",
336
- "Content-type" => "application/soap+xml; charset=UTF-8",
337
- "Content-length" => request.bytesize.to_s
338
- })
330
+ req = Net::HTTP::Post.new(uri.request_uri,
331
+ 'Connection' => 'Keep-Alive',
332
+ 'Content-type' => 'application/soap+xml; charset=UTF-8',
333
+ 'Content-length' => request.bytesize.to_s
334
+ )
339
335
  req.body = request
340
336
  response = http.request(req)
341
337
 
342
- if response.code.to_i == 200
343
- response_body = response.body
344
- else
345
- # Do something here on error.
346
- end
347
-
348
- log_xml("RESPONSE", response_body)
338
+ response_body = response.body
339
+ log_xml('RESPONSE', response_body)
349
340
 
350
341
  response_body
351
342
  end
@@ -354,6 +345,7 @@ module DynamicsCRM
354
345
  return unless logger
355
346
 
356
347
  logger.debug(title)
348
+
357
349
  doc = REXML::Document.new(xml)
358
350
  formatter.write(doc.root, logger)
359
351
  logger.debug("\n")
@@ -1,13 +1,10 @@
1
1
  module DynamicsCRM
2
2
  module Response
3
-
4
3
  class Result < Hash
5
-
6
4
  attr_reader :document
7
5
  attr_reader :result_response
8
6
 
9
7
  def initialize(xml)
10
-
11
8
  @document = REXML::Document.new(xml)
12
9
 
13
10
  fault_xml = @document.get_elements("//[local-name() = 'Fault']")
@@ -24,7 +21,7 @@ module DynamicsCRM
24
21
 
25
22
  # Returns base element of the response document to parse.
26
23
  def response_element
27
- class_name = self.class.to_s.split("::").last
24
+ class_name = self.class.to_s.split('::').last
28
25
  end
29
26
 
30
27
  # Invoked by constructor, should be implemented in sub-classes.
@@ -35,7 +32,6 @@ module DynamicsCRM
35
32
 
36
33
  # Allows method-like access to the hash using camelcase field names.
37
34
  def method_missing(method, *args, &block)
38
-
39
35
  # First return local hash entry for symbol or string.
40
36
  return self[method] if self.has_key?(method)
41
37
 
@@ -50,13 +46,12 @@ module DynamicsCRM
50
46
  end
51
47
 
52
48
  # Finally return nil.
53
- return value
49
+ value
54
50
  end
55
51
 
56
52
  def respond_to_missing?(method_name, include_private = false)
57
53
  self.has_key?(method_name.to_s) || self.has_key?(method_name) || super
58
54
  end
59
-
60
55
  end
61
56
 
62
57
  # There's nothing to parse in the UpdateResult
@@ -73,6 +68,5 @@ module DynamicsCRM
73
68
 
74
69
  class DisassociateResponse < Result
75
70
  end
76
-
77
71
  end
78
72
  end
@@ -1,3 +1,3 @@
1
1
  module DynamicsCRM
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -51,8 +51,8 @@ module DynamicsCRM
51
51
  end
52
52
  end
53
53
 
54
- if type == "string" && value =~ /\w+{8}-\w+{4}-\w+{4}-\w+{4}-\w+{12}/
55
- type = "guid"
54
+ if type == 'string' && value =~ /\A\{?\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}?\z/
55
+ type = 'guid'
56
56
  end
57
57
 
58
58
  type
@@ -4,9 +4,11 @@ module DynamicsCRM
4
4
  # Creates a ConditionExpression element to be used in retrieve calls.
5
5
  class ConditionExpression
6
6
  attr_accessor :attr_name, :operator, :value, :type
7
- def initialize(attr_name, operator, value, type: nil)
7
+
8
+ def initialize(attr_name, operator, value = nil, type: nil)
8
9
  @attr_name = attr_name
9
10
  @operator = operator
11
+ # value can be optional to support Null and NotNull operators
10
12
  @value = value
11
13
  @values = Array(value)
12
14
  @type = type
@@ -2,6 +2,7 @@ module DynamicsCRM
2
2
  module XML
3
3
  class Criteria < Array
4
4
  SUPPORTED_OPERATORS = %w(And Or)
5
+ attr_accessor :filter_operator
5
6
 
6
7
  def initialize(tuples = [], filter_operator: nil)
7
8
  filter_operator ||= 'And'
@@ -15,31 +16,59 @@ module DynamicsCRM
15
16
  attr_name, operator, value, data_type = *tuple
16
17
  ConditionExpression.new(attr_name, operator, value, type: data_type)
17
18
  end
19
+
20
+ @filters = []
18
21
  end
19
22
 
20
- def add_condition(attr_name, operator, value, type: nil)
23
+ def add_condition(attr_name, operator, value = nil, type: nil)
21
24
  @expressions << ConditionExpression.new(attr_name, operator, value, type: type)
22
25
  end
23
26
 
27
+ def add_filter(filter)
28
+ @filters << filter
29
+ end
30
+
24
31
  # ConditionExpression can be repeated multiple times
25
32
  # Operator: can be lots of values such as: eq (Equals), neq (Not Equals), gt (Greater Than)
26
33
  # get the values from a fetch xml query
27
34
  # Values -> Value can be repeated multiple times
28
35
  # FilterOperator: and OR or depending on the filter requirements
36
+ # Filters: can contain FilterExpressions to support complex logical statements.
29
37
  def to_xml(options = {})
30
38
  ns = options[:namespace] ? options[:namespace] : 'a'
31
39
 
32
- xml_expression = @expressions.map do |conditional|
33
- conditional.to_xml(options)
34
- end.join('')
35
-
36
40
  %(<#{ns}:Criteria>
37
- <#{ns}:Conditions>
38
- #{xml_expression}
39
- </#{ns}:Conditions>
41
+ #{conditions_xml(options)}
40
42
  <#{ns}:FilterOperator>#{@filter_operator}</#{ns}:FilterOperator>
43
+ #{filters_xml(options)}
41
44
  </#{ns}:Criteria>)
42
45
  end
46
+
47
+ def conditions_xml(options)
48
+ ns = options[:namespace] ? options[:namespace] : 'a'
49
+
50
+ if @expressions.empty?
51
+ "<#{ns}:Conditions />"
52
+ else
53
+ xml_expression = @expressions.map do |conditional|
54
+ conditional.to_xml(options)
55
+ end.join('')
56
+
57
+ %(<#{ns}:Conditions>
58
+ #{xml_expression}
59
+ </#{ns}:Conditions>)
60
+ end
61
+ end
62
+
63
+ def filters_xml(options)
64
+ ns = options[:namespace] ? options[:namespace] : 'a'
65
+ if @filters.empty?
66
+ "<#{ns}:Filters />"
67
+ else
68
+ fx = @filters.map { |f| f.to_xml(options) }.join('')
69
+ %(<#{ns}:Filters>#{fx}</#{ns}:Filters>)
70
+ end
71
+ end
43
72
  end
44
73
  # Criteria
45
74
  end
@@ -0,0 +1,65 @@
1
+ module DynamicsCRM
2
+ module XML
3
+ # Represents FilterExpression XML fragment.
4
+ class FilterExpression
5
+ attr_accessor :conditions, :filters, :filter_operator
6
+
7
+ def initialize(operator = 'And')
8
+ @filter_operator = operator
9
+ @conditions = []
10
+ @filters = []
11
+ end
12
+
13
+ def add_condition(field, operator, value=nil)
14
+ conditions << ConditionExpression.new(field, operator, value)
15
+ end
16
+
17
+ def add_filter(filter)
18
+ filters << filter
19
+ end
20
+
21
+ def to_xml(options = {})
22
+ ns = options[:namespace] ? options[:namespace] : 'b'
23
+
24
+ query_xml = %(
25
+ <#{ns}:FilterExpression>
26
+ #{conditions_xml(options)}
27
+ <#{ns}:FilterOperator>#{@filter_operator}</#{ns}:FilterOperator>
28
+ #{filters_xml(options)}
29
+ </#{ns}:FilterExpression>
30
+ )
31
+
32
+ query_xml
33
+ end
34
+
35
+ protected
36
+
37
+ def conditions_xml(options)
38
+ ns = options[:namespace] ? options[:namespace] : 'b'
39
+
40
+ if conditions.empty?
41
+ "<#{ns}:Conditions />"
42
+ else
43
+ xml = conditions.map { |c| c.to_xml(options) }.join('')
44
+ %(<#{ns}:Conditions>
45
+ #{xml}
46
+ </#{ns}:Conditions>)
47
+ end
48
+ end
49
+
50
+ def filters_xml(options)
51
+ ns = options[:namespace] ? options[:namespace] : 'b'
52
+
53
+ if filters.empty?
54
+ "<#{ns}:Filters />"
55
+ else
56
+ sub_filters = filters.map { |f| f.to_xml(options) }.join('')
57
+ %(<#{ns}:Filters>
58
+ #{sub_filters}
59
+ </#{ns}:Filters>)
60
+ end
61
+ end
62
+ end
63
+ # FilterExpression
64
+ end
65
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe DynamicsCRM::XML::ConditionExpression do
4
+ it 'generates base ConditionExpresion' do
5
+ subject = DynamicsCRM::XML::ConditionExpression.new('name', 'Equal', 'GitHub')
6
+
7
+ fragment = %(
8
+ <b:ConditionExpression>
9
+ <b:AttributeName>name</b:AttributeName>
10
+ <b:Operator>Equal</b:Operator>
11
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
12
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">GitHub</d:anyType>
13
+ </b:Values>
14
+ </b:ConditionExpression>)
15
+
16
+ expect(subject.to_xml(namespace: 'b')).to match_xml fragment
17
+ end
18
+
19
+ it 'supports boolean values' do
20
+ subject = DynamicsCRM::XML::ConditionExpression.new('isactive', 'Equal', true)
21
+
22
+ fragment = %(
23
+ <b:ConditionExpression>
24
+ <b:AttributeName>isactive</b:AttributeName>
25
+ <b:Operator>Equal</b:Operator>
26
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
27
+ <d:anyType i:type="s:boolean" xmlns:s="http://www.w3.org/2001/XMLSchema">true</d:anyType>
28
+ </b:Values>
29
+ </b:ConditionExpression>)
30
+
31
+ expect(subject.to_xml(namespace: 'b')).to match_xml fragment
32
+ end
33
+
34
+ it 'supports Array values' do
35
+ subject = DynamicsCRM::XML::ConditionExpression.new('salesstage', 'In', [0, 1, 2])
36
+
37
+ fragment = %(
38
+ <b:ConditionExpression>
39
+ <b:AttributeName>salesstage</b:AttributeName>
40
+ <b:Operator>In</b:Operator>
41
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
42
+ <d:anyType i:type="s:int" xmlns:s="http://www.w3.org/2001/XMLSchema">0</d:anyType>
43
+ <d:anyType i:type="s:int" xmlns:s="http://www.w3.org/2001/XMLSchema">1</d:anyType>
44
+ <d:anyType i:type="s:int" xmlns:s="http://www.w3.org/2001/XMLSchema">2</d:anyType>
45
+ </b:Values>
46
+ </b:ConditionExpression>)
47
+
48
+ expect(subject.to_xml(namespace: 'b')).to match_xml fragment
49
+ end
50
+
51
+ it 'supports Null operator without value' do
52
+ subject = DynamicsCRM::XML::ConditionExpression.new('telephone1', 'Null')
53
+
54
+ fragment = %(
55
+ <b:ConditionExpression>
56
+ <b:AttributeName>telephone1</b:AttributeName>
57
+ <b:Operator>Null</b:Operator>
58
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
59
+ </b:Values>
60
+ </b:ConditionExpression>)
61
+
62
+ expect(subject.to_xml(namespace: 'b')).to match_xml fragment
63
+ end
64
+ end
@@ -8,9 +8,9 @@ describe DynamicsCRM::XML::Criteria do
8
8
 
9
9
  it 'generates empty Criteria fragment' do
10
10
  expected = %(<a:Criteria>
11
- <a:Conditions>
12
- </a:Conditions>
11
+ <a:Conditions />
13
12
  <a:FilterOperator>And</a:FilterOperator>
13
+ <a:Filters />
14
14
  </a:Criteria>)
15
15
 
16
16
  expect(subject.to_xml).to match_xml(expected)
@@ -33,6 +33,7 @@ describe DynamicsCRM::XML::Criteria do
33
33
  </a:ConditionExpression>
34
34
  </a:Conditions>
35
35
  <a:FilterOperator>And</a:FilterOperator>
36
+ <a:Filters />
36
37
  </a:Criteria>)
37
38
  }
38
39
 
@@ -77,6 +78,7 @@ describe DynamicsCRM::XML::Criteria do
77
78
  </a:ConditionExpression>
78
79
  </a:Conditions>
79
80
  <a:FilterOperator>And</a:FilterOperator>
81
+ <a:Filters />
80
82
  </a:Criteria>)
81
83
  end
82
84
  end
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ describe DynamicsCRM::XML::FilterExpression do
4
+ describe 'initialization' do
5
+ subject {
6
+ DynamicsCRM::XML::FilterExpression.new('And')
7
+ }
8
+
9
+ it 'generates empty FilterExpression fragment' do
10
+ fragment = %(<b:FilterExpression>
11
+ <b:Conditions />
12
+ <b:FilterOperator>And</b:FilterOperator>
13
+ <b:Filters />
14
+ </b:FilterExpression>)
15
+
16
+ expect(subject.to_xml).to match_xml fragment
17
+ end
18
+
19
+ it 'generates FilterExpression with condition' do
20
+ subject.add_condition('name', 'Equal', 'Integration Specialists')
21
+
22
+ fragment = %(
23
+ <b:FilterExpression>
24
+ <b:Conditions>
25
+ <b:ConditionExpression>
26
+ <b:AttributeName>name</b:AttributeName>
27
+ <b:Operator>Equal</b:Operator>
28
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
29
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">Integration Specialists</d:anyType>
30
+ </b:Values>
31
+ </b:ConditionExpression>
32
+ </b:Conditions>
33
+ <b:FilterOperator>And</b:FilterOperator>
34
+ <b:Filters />
35
+ </b:FilterExpression>)
36
+
37
+ expect(subject.to_xml(namespace: 'b')).to match_xml fragment
38
+ end
39
+
40
+ it 'generates FilterExpression with sub-Filter' do
41
+ subject.add_condition('name', 'Equal', 'Integration Specialists')
42
+
43
+ filter = DynamicsCRM::XML::FilterExpression.new('And')
44
+ filter.add_condition('name', 'NotEqual', 'Bob')
45
+
46
+ subject.add_filter(filter)
47
+
48
+ fragment = %(
49
+ <b:FilterExpression>
50
+ <b:Conditions>
51
+ <b:ConditionExpression>
52
+ <b:AttributeName>name</b:AttributeName>
53
+ <b:Operator>Equal</b:Operator>
54
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
55
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">Integration Specialists</d:anyType>
56
+ </b:Values>
57
+ </b:ConditionExpression>
58
+ </b:Conditions>
59
+ <b:FilterOperator>And</b:FilterOperator>
60
+ <b:Filters>
61
+ <b:FilterExpression>
62
+ <b:Conditions>
63
+ <b:ConditionExpression>
64
+ <b:AttributeName>name</b:AttributeName>
65
+ <b:Operator>NotEqual</b:Operator>
66
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
67
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">Bob</d:anyType>
68
+ </b:Values>
69
+ </b:ConditionExpression>
70
+ </b:Conditions>
71
+ <b:FilterOperator>And</b:FilterOperator>
72
+ <b:Filters />
73
+ </b:FilterExpression>
74
+ </b:Filters>
75
+ </b:FilterExpression>)
76
+
77
+ expect(subject.to_xml(namespace: 'b')).to match_xml fragment
78
+ end
79
+ end
80
+
81
+ describe 'Criteria' do
82
+ subject do
83
+ criteria = DynamicsCRM::XML::Criteria.new
84
+ criteria.filter_operator = 'Or'
85
+
86
+ filter1 = DynamicsCRM::XML::FilterExpression.new('And')
87
+ filter1.add_condition('name', 'Equal', 'Integration Specialists')
88
+ filter1.add_condition('name', 'NotEqual', 'Bob')
89
+
90
+ filter2 = DynamicsCRM::XML::FilterExpression.new('And')
91
+ filter2.add_condition('name', 'Equal', 'Thematics Development Inc.')
92
+ filter2.add_condition('name', 'NotEqual', 'Bob')
93
+
94
+ criteria.add_filter(filter1)
95
+ criteria.add_filter(filter2)
96
+
97
+ criteria
98
+ end
99
+
100
+ it 'generates Criteria with Or Filters' do
101
+ expect(subject.to_xml(namespace: 'b')).to match_xml criteria_with_or_filters
102
+ end
103
+
104
+ def criteria_with_or_filters
105
+ %(<b:Criteria>
106
+ <b:Conditions />
107
+ <b:FilterOperator>Or</b:FilterOperator>
108
+ <b:Filters>
109
+ <b:FilterExpression>
110
+ <b:Conditions>
111
+ <b:ConditionExpression>
112
+ <b:AttributeName>name</b:AttributeName>
113
+ <b:Operator>Equal</b:Operator>
114
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
115
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">Integration Specialists</d:anyType>
116
+ </b:Values>
117
+ </b:ConditionExpression>
118
+ <b:ConditionExpression>
119
+ <b:AttributeName>name</b:AttributeName>
120
+ <b:Operator>NotEqual</b:Operator>
121
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
122
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">Bob</d:anyType>
123
+ </b:Values>
124
+ </b:ConditionExpression>
125
+ </b:Conditions>
126
+ <b:FilterOperator>And</b:FilterOperator>
127
+ <b:Filters />
128
+ </b:FilterExpression>
129
+ <b:FilterExpression>
130
+ <b:Conditions>
131
+ <b:ConditionExpression>
132
+ <b:AttributeName>name</b:AttributeName>
133
+ <b:Operator>Equal</b:Operator>
134
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
135
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">Thematics Development Inc.</d:anyType>
136
+ </b:Values>
137
+ </b:ConditionExpression>
138
+ <b:ConditionExpression>
139
+ <b:AttributeName>name</b:AttributeName>
140
+ <b:Operator>NotEqual</b:Operator>
141
+ <b:Values xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
142
+ <d:anyType i:type="s:string" xmlns:s="http://www.w3.org/2001/XMLSchema">Bob</d:anyType>
143
+ </b:Values>
144
+ </b:ConditionExpression>
145
+ </b:Conditions>
146
+ <b:FilterOperator>And</b:FilterOperator>
147
+ <b:Filters />
148
+ </b:FilterExpression>
149
+ </b:Filters>
150
+ </b:Criteria>)
151
+ end
152
+ end
153
+ end
@@ -9,7 +9,8 @@ describe DynamicsCRM::XML::QueryExpression do
9
9
 
10
10
  context "generate empty QueryExpression fragment" do
11
11
  it { expect(subject.to_xml).to include("<b:ColumnSet ") }
12
- it { expect(subject.to_xml).to match(/<b:Conditions>\s+<\/b:Conditions>/) }
12
+ it { expect(subject.to_xml).to include("<b:Criteria>") }
13
+ it { expect(subject.to_xml).to include("<b:Conditions />") }
13
14
  it { expect(subject.to_xml).to include("<b:AllColumns>true</b:AllColumns>") }
14
15
  it { expect(subject.to_xml).to include("<b:Distinct>false</b:Distinct>") }
15
16
  it { expect(subject.to_xml).to include("<b:EntityName>opportunity</b:EntityName>") }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamics_crm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Heth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-22 00:00:00.000000000 Z
11
+ date: 2017-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mimemagic
@@ -190,6 +190,7 @@ files:
190
190
  - lib/dynamics_crm/xml/entity_reference.rb
191
191
  - lib/dynamics_crm/xml/fault.rb
192
192
  - lib/dynamics_crm/xml/fetch_expression.rb
193
+ - lib/dynamics_crm/xml/filter_expression.rb
193
194
  - lib/dynamics_crm/xml/message_builder.rb
194
195
  - lib/dynamics_crm/xml/message_parser.rb
195
196
  - lib/dynamics_crm/xml/money.rb
@@ -235,10 +236,12 @@ files:
235
236
  - spec/lib/response/retrieve_result_spec.rb
236
237
  - spec/lib/xml/attributes_spec.rb
237
238
  - spec/lib/xml/column_set_spec.rb
239
+ - spec/lib/xml/condition_expression_spec.rb
238
240
  - spec/lib/xml/criteria_spec.rb
239
241
  - spec/lib/xml/entity_reference_spec.rb
240
242
  - spec/lib/xml/entity_spec.rb
241
243
  - spec/lib/xml/fault_spec.rb
244
+ - spec/lib/xml/filter_expression_spec.rb
242
245
  - spec/lib/xml/message_builder_spec.rb
243
246
  - spec/lib/xml/money_spec.rb
244
247
  - spec/lib/xml/query_expression_spec.rb
@@ -309,10 +312,12 @@ test_files:
309
312
  - spec/lib/response/retrieve_result_spec.rb
310
313
  - spec/lib/xml/attributes_spec.rb
311
314
  - spec/lib/xml/column_set_spec.rb
315
+ - spec/lib/xml/condition_expression_spec.rb
312
316
  - spec/lib/xml/criteria_spec.rb
313
317
  - spec/lib/xml/entity_reference_spec.rb
314
318
  - spec/lib/xml/entity_spec.rb
315
319
  - spec/lib/xml/fault_spec.rb
320
+ - spec/lib/xml/filter_expression_spec.rb
316
321
  - spec/lib/xml/message_builder_spec.rb
317
322
  - spec/lib/xml/money_spec.rb
318
323
  - spec/lib/xml/query_expression_spec.rb