Class: Cherby::BusinessObject

Inherits:
Object
  • Object
show all
Defined in:
lib/cherby/business_object.rb

Overview

Cherwell BusinessObject wrapper, with data represented as an XML DOM

Direct Known Subclasses

Incident, JournalNote, Task

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xml) ⇒ BusinessObject

Create a new instance populated with the given XML string



38
39
40
# File 'lib/cherby/business_object.rb', line 38

def initialize(xml)
  @dom = Nokogiri::XML(xml)
end

Class Attribute Details

.default_valuesObject

Returns the value of attribute default_values.



13
14
15
# File 'lib/cherby/business_object.rb', line 13

def default_values
  @default_values
end

.object_nameObject

Returns the value of attribute object_name.



13
14
15
# File 'lib/cherby/business_object.rb', line 13

def object_name
  @object_name
end

Instance Attribute Details

#domObject (readonly)

Instance methods



35
36
37
# File 'lib/cherby/business_object.rb', line 35

def dom
  @dom
end

Class Method Details

.create(fields = {}) ⇒ Object

Create a new BusinessObject subclass instance from the given hash of 'FieldName' => 'Field Value'.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/cherby/business_object.rb', line 18

def self.create(fields={})
  type_name = self.object_name
  builder = Nokogiri::XML::Builder.new {
    BusinessObject_('Name' => type_name, 'RecID' => 'TODO') {
      FieldList_ {
        fields.each { |name, value|
          Field_(value, 'Name' => name)
        }
      }
      RelationshipList_ { }
    }
  }
  return self.new(builder.to_xml)
end

.parse_datetime(dt_string, tz_offset = -5)) ⇒ Object

Parse a Cherwell date/time string and return a DateTime object in UTC.

This method mostly exists to work around the fact that Cherwell does not report a time zone offset in its datestamps. Since a BusinessObject may be initialized from a Jira entity (which does store time zone offset), any dt_string that includes a time zone offset at the end is correctly included in the result.

Parameters:

  • dt_string (String)

    The date/time string to parse. May or may not include a trailing [+-]HH:MM or [+-]HHMM.

  • tz_offset (Integer) (defaults to: -5))

    Offset in hours (positive or negative) between UTC and the given dt_string. For example, Eastern Time is -5. This is ONLY used if dt_string does NOT include a trailing offset component.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/cherby/business_object.rb', line 88

def self.parse_datetime(dt_string, tz_offset=-5)
  begin
    result = DateTime.parse(dt_string)
  rescue
    raise ArgumentError, "Could not parse date/time '#{dt_string}'"
  end
  # If offset was part of the dt_string, use new_offset to get UTC
  if dt_string =~ /[+-]\d\d:?\d\d$/
    return result.new_offset(0)
  # Otherwise, subtract the numeric offset to get UTC time
  else
    return result - Rational(tz_offset.to_i, 24)
  end
end

Instance Method Details

#[](field_name) ⇒ Object

Return the content in the field with the given name. TODO: Exception for unknown field name



130
131
132
133
134
# File 'lib/cherby/business_object.rb', line 130

def [](field_name)
  if field = get_field_node(field_name)
    return field.content
  end
end

#[]=(field_name, value) ⇒ Object

Modify the content in the field with the given name. TODO: Exception for unknown field name



138
139
140
141
142
# File 'lib/cherby/business_object.rb', line 138

def []=(field_name, value)
  if field = get_field_node(field_name)
    field.content = value.to_s
  end
end

#copy_fields_from(other_object, *field_names) ⇒ Object

Copy designated fields from one BusinessObject to another.

Examples:

object_a.copy_fields_from(object_b, 'Status', 'Description')
# object_a['Status']      = object_b['Status']
# object_a['Description'] = object_b['Description']

Parameters:

  • other_object (BusinessObject)

    The object to copy field values from

  • field_names (Array<String>)

    Names of fields whose values you want to copy



156
157
158
159
160
# File 'lib/cherby/business_object.rb', line 156

def copy_fields_from(other_object, *field_names)
  field_names.each do |field|
    self[field] = other_object[field]
  end
end

#get_field_node(field_name) ⇒ Object

Return the node of the field with the given name.



48
49
50
51
52
53
54
55
56
57
# File 'lib/cherby/business_object.rb', line 48

def get_field_node(field_name)
  selector = "BusinessObject > FieldList > Field[@Name=#{field_name}]"
  element = @dom.css(selector).first
  if element.nil?
    element = Nokogiri::XML::Node.new('Field', @dom)
    element['Name'] = field_name
    @dom.at_css("BusinessObject > FieldList").add_child(element)
  end
  return element
end

#mod_sObject

Return the last-modified time as a human-readable string



118
119
120
# File 'lib/cherby/business_object.rb', line 118

def mod_s
  return modified.strftime('%Y-%m-%d %H:%M:%S')
end

#modifiedObject

Return the last-modified date/time of this BusinessObject (LastModDateTime converted to DateTime)



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/cherby/business_object.rb', line 105

def modified
  last_mod = self['LastModDateTime']
  if last_mod.nil? || last_mod.empty?
    raise RuntimeError, "BusinessObject is missing LastModDateTime field."
  end
  begin
    return BusinessObject.parse_datetime(last_mod)
  rescue(ArgumentError)
    raise RuntimeError, "Cannot parse LastModDateTime: '#{last_mod}'"
  end
end

#newer_than?(business_object) ⇒ Boolean

Return True if this BusinessObject was modified more recently than another BusinessObject.

Returns:

  • (Boolean)


124
125
126
# File 'lib/cherby/business_object.rb', line 124

def newer_than?(business_object)
  return modified > business_object.modified
end

#to_hashObject Also known as: field_values

Return a hash of field names and values



60
61
62
63
64
65
66
67
# File 'lib/cherby/business_object.rb', line 60

def to_hash
  result = {}
  selector = "BusinessObject > FieldList > Field"
  @dom.css(selector).each do |node|
    result[node['Name']] = node.content
  end
  return result
end

#to_xmlObject

Return the XML representation of this BusinessObject



43
44
45
# File 'lib/cherby/business_object.rb', line 43

def to_xml
  return @dom.to_xml
end