erp_base_erp_svcs 4.0.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v1/base_controller.rb +17 -0
  3. data/app/controllers/api/v1/categories_controller.rb +165 -0
  4. data/app/controllers/api/v1/contact_purposes_controller.rb +24 -0
  5. data/app/controllers/api/v1/geo_zones_controller.rb +25 -0
  6. data/app/controllers/api/v1/note_types_controller.rb +27 -0
  7. data/app/controllers/api/v1/parties_controller.rb +182 -0
  8. data/app/controllers/api/v1/role_types_controller.rb +146 -0
  9. data/app/controllers/api/v1/status_applications_controller.rb +40 -0
  10. data/app/controllers/api/v1/tracked_status_types_controller.rb +146 -0
  11. data/app/controllers/api/v1/unit_of_measurements_controller.rb +16 -0
  12. data/app/models/category.rb +116 -4
  13. data/app/models/contact.rb +16 -2
  14. data/app/models/contact_purpose.rb +13 -0
  15. data/app/models/descriptive_asset.rb +17 -0
  16. data/app/models/email_address.rb +21 -3
  17. data/app/models/entity_party_role.rb +8 -0
  18. data/app/models/fixed_asset.rb +2 -0
  19. data/app/models/fixed_asset_type.rb +1 -0
  20. data/app/models/generated_item.rb +17 -0
  21. data/app/models/geo_country.rb +12 -1
  22. data/app/models/individual.rb +11 -20
  23. data/app/models/note.rb +9 -0
  24. data/app/models/note_type.rb +2 -0
  25. data/app/models/organization.rb +19 -16
  26. data/app/models/party.rb +134 -229
  27. data/app/models/party_unit_of_measurement.rb +17 -1
  28. data/app/models/phone_number.rb +32 -12
  29. data/app/models/postal_address.rb +42 -11
  30. data/app/models/relationship_type.rb +28 -1
  31. data/app/models/role_type.rb +25 -2
  32. data/app/models/status_application.rb +40 -0
  33. data/app/models/tracked_status_type.rb +12 -0
  34. data/app/models/unit_of_measurement.rb +46 -7
  35. data/app/models/view_type.rb +14 -0
  36. data/config/routes.rb +24 -0
  37. data/db/data_migrations/20110913145838_setup_compass_ae_instance.rb +22 -9
  38. data/db/migrate/20080805000020_base_erp_services.rb +235 -6
  39. data/db/migrate/20130713171653_create_party_unit_of_measurements.rb +28 -0
  40. data/db/migrate/20150716201200_add_record_to_contact.rb +42 -0
  41. data/db/migrate/20150814202823_add_party_id_to_status_application.rb +10 -0
  42. data/db/migrate/20160310163040_add_created_by_updated_by_to_erp_base_erp_svcs.rb +44 -0
  43. data/lib/erp_base_erp_svcs.rb +1 -0
  44. data/lib/erp_base_erp_svcs/config.rb +3 -2
  45. data/lib/erp_base_erp_svcs/engine.rb +8 -1
  46. data/lib/erp_base_erp_svcs/extensions.rb +7 -1
  47. data/lib/erp_base_erp_svcs/extensions/active_record/acts_as_category.rb +5 -4
  48. data/lib/erp_base_erp_svcs/extensions/active_record/acts_as_erp_type.rb +48 -9
  49. data/lib/erp_base_erp_svcs/extensions/active_record/can_be_generated.rb +54 -0
  50. data/lib/erp_base_erp_svcs/extensions/active_record/has_contacts.rb +383 -0
  51. data/lib/erp_base_erp_svcs/extensions/active_record/has_notes.rb +15 -4
  52. data/lib/erp_base_erp_svcs/extensions/active_record/has_party_roles.rb +94 -0
  53. data/lib/erp_base_erp_svcs/extensions/active_record/has_tracked_status.rb +118 -35
  54. data/lib/erp_base_erp_svcs/extensions/active_record/is_contact_mechanism.rb +94 -0
  55. data/lib/erp_base_erp_svcs/extensions/active_record/is_describable.rb +46 -42
  56. data/lib/erp_base_erp_svcs/extensions/active_record/is_tenantable.rb +40 -0
  57. data/lib/erp_base_erp_svcs/extensions/active_record/tracks_created_by_updated_by.rb +39 -0
  58. data/lib/erp_base_erp_svcs/extensions/core/numbers.rb +29 -18
  59. data/lib/erp_base_erp_svcs/extensions/core/object.rb +5 -0
  60. data/lib/erp_base_erp_svcs/extensions/core/string.rb +53 -0
  61. data/lib/erp_base_erp_svcs/non_escape_json_string.rb +1 -1
  62. data/lib/erp_base_erp_svcs/time_zone_helper.rb +57 -0
  63. data/lib/erp_base_erp_svcs/version.rb +1 -1
  64. data/lib/tasks/erp_base_erp_svcs_tasks.rake +20 -23
  65. data/spec/dummy/log/development.log +3 -0
  66. metadata +29 -22
  67. data/db/data_migrations/20110525001935_add_usd_currency.rb +0 -11
  68. data/db/data_migrations/20110609150135_add_iso_codes.rb +0 -18
  69. data/db/data_migrations/20130211555555_upgrade_compass_ae_instances_data.rb +0 -18
  70. data/db/data_migrations/20130404201756_add_guid_to_instances.rb +0 -9
  71. data/db/migrate/20120606183856_add_txn_status.rb +0 -36
  72. data/db/migrate/20130211444444_upgrade_compass_ae_instances.rb +0 -33
  73. data/db/migrate/20130404171435_add_uuid_compass_ae_instance.rb +0 -16
  74. data/db/migrate/20130411125210_add_long_lat_to_address.rb +0 -15
  75. data/db/migrate/20130522125404_create_facilities.rb +0 -114
  76. data/db/migrate/20130621182047_create_unit_of_measurements.rb +0 -18
  77. data/db/migrate/20130909163912_add_iid_index_to_role_types.rb +0 -9
  78. data/db/migrate/20130926023541_add_domain_to_unit_of_measure.rb +0 -13
  79. data/db/migrate/20130929025342_add_type_semantics_to_uom.rb +0 -54
  80. data/db/migrate/20131112013047_add_primary_to_contacts.rb +0 -13
  81. data/db/migrate/20131112013048_add_erp_base_erp_svcs_missing_indexes.rb +0 -33
  82. data/db/migrate/20131211180831_add_postal_address_to_facility.rb +0 -5
  83. data/db/migrate/20140102154311_create_fixed_asset_party_roles.rb +0 -12
  84. data/db/migrate/20140401072612_add_custom_fields_to_party.rb +0 -12
  85. data/lib/erp_base_erp_svcs/extensions/active_record/has_contact.rb +0 -69
@@ -1,9 +1,11 @@
1
1
  class Contact < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
+ tracks_created_by_updated_by
5
+
4
6
  has_and_belongs_to_many :contact_purposes
5
- belongs_to :party
6
7
  belongs_to :contact_mechanism, :polymorphic => true, :dependent => :destroy
8
+ belongs_to :contact_record, :polymorphic => true
7
9
 
8
10
  #rather than carry our own description for the abstract -contact-, we'll
9
11
  #delegate that call to the implementer of the -contact_mechanism- interface
@@ -16,6 +18,18 @@ class Contact < ActiveRecord::Base
16
18
  @description=d
17
19
  end
18
20
 
21
+ def party
22
+ if self.contact_record_type == 'Party'
23
+ self.contact_record
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def party=(party)
30
+ self.contact_record = party
31
+ end
32
+
19
33
  #delegate our need to provide a label to scaffolds to the implementer of
20
34
  #the -contact_mechanism- interface.
21
35
 
@@ -26,7 +40,7 @@ class Contact < ActiveRecord::Base
26
40
  def summary_line
27
41
  "#{contact_mechanism.summary_line}"
28
42
  end
29
-
43
+
30
44
  def is_primary?
31
45
  self.is_primary
32
46
  end
@@ -5,4 +5,17 @@ class ContactPurpose < ActiveRecord::Base
5
5
  acts_as_erp_type
6
6
 
7
7
  has_and_belongs_to_many :contacts
8
+
9
+ def to_data_hash
10
+ to_hash(
11
+ only: [
12
+ :id,
13
+ :description,
14
+ :internal_identifier,
15
+ :created_at,
16
+ :updated_at
17
+ ],
18
+ leaf: leaf?
19
+ )
20
+ end
8
21
  end
@@ -1,6 +1,23 @@
1
+ # create_table :descriptive_assets do |t|
2
+ # t.references :view_type
3
+ # t.string :internal_identifier
4
+ # t.text :description
5
+ # t.string :external_identifier
6
+ # t.string :external_id_source
7
+ # t.references :described_record, :polymorphic => true
8
+ #
9
+ # t.timestamps
10
+ # end
11
+ #
12
+ # add_index :descriptive_assets, :view_type_id
13
+ # add_index :descriptive_assets, [:described_record_id, :described_record_type], :name => 'described_record_idx'
14
+
1
15
  class DescriptiveAsset < ActiveRecord::Base
2
16
  attr_protected :created_at, :updated_at
3
17
 
18
+ tracks_created_by_updated_by
19
+
4
20
  belongs_to :view_type
5
21
  belongs_to :described_record, :polymorphic => true
22
+
6
23
  end
@@ -1,10 +1,19 @@
1
+ # create_table :email_addresses do |t|
2
+ # t.column :email_address, :string
3
+ # t.column :description, :string
4
+ #
5
+ # t.timestamps
6
+ # end
7
+
1
8
  class EmailAddress < ActiveRecord::Base
2
9
  attr_protected :created_at, :updated_at
3
10
 
4
- has_contact
11
+ is_contact_mechanism
12
+
13
+ validates_format_of :email_address,
14
+ with: /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/,
15
+ message: "Must be a valid email address"
5
16
 
6
- validates_format_of :email_address, :with => /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/, :message => "Must be a valid email address"
7
-
8
17
  def summary_line
9
18
  "#{description} : #{email_address}"
10
19
  end
@@ -17,4 +26,13 @@ class EmailAddress < ActiveRecord::Base
17
26
  "#{email_address}"
18
27
  end
19
28
 
29
+ def to_data_hash
30
+ to_hash(only: [
31
+ :email_address,
32
+ :description,
33
+ :created_at,
34
+ :updated_at
35
+ ])
36
+ end
37
+
20
38
  end
@@ -0,0 +1,8 @@
1
+ class EntityPartyRole < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ belongs_to :party
5
+ belongs_to :role_type
6
+ belongs_to :entity_record, :polymorphic => true
7
+
8
+ end
@@ -1,6 +1,8 @@
1
1
  class FixedAsset < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
+ tracks_created_by_updated_by
5
+
4
6
  belongs_to :fixed_asset_type
5
7
  belongs_to :fixed_asset_record, :polymorphic => true
6
8
  has_many :fixed_asset_party_roles
@@ -1,6 +1,7 @@
1
1
  class FixedAssetType < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
+ acts_as_erp_type
4
5
  acts_as_nested_set
5
6
  include ErpTechSvcs::Utils::DefaultNestedSetMethods
6
7
 
@@ -0,0 +1,17 @@
1
+ # create_table :generated_items do |t|
2
+ # t.references :generated_by, :polymorphic => true
3
+ # t.references :generated_record, :polymorphic => true
4
+ #
5
+ # t.timestamps
6
+ # end
7
+ #
8
+ # add_index :generated_items, [:generated_by_type, :generated_by_id], :name => 'generated_by_idx'
9
+ # add_index :generated_items, [:generated_record_type, :generated_record_id], :name => 'generated_record_idx'
10
+
11
+ class GeneratedItem < ActiveRecord::Base
12
+ attr_protected :created_at, :updated_at
13
+
14
+ belongs_to :generated_record, :polymorphic => true
15
+ belongs_to :generated_by, :polymorphic => true
16
+
17
+ end
@@ -7,5 +7,16 @@ class GeoCountry < ActiveRecord::Base
7
7
  validates :name, :presence => {:message => 'Name cannot be blank'}
8
8
  validates :iso_code_2, :presence => {:message => 'ISO code 2 cannot be blank'}
9
9
  validates :iso_code_3, :presence => {:message => 'ISO code 3 cannot be blank'}
10
-
10
+
11
+ class << self
12
+
13
+ def countries_with_us_first
14
+ countries = where('iso_code_2 <> ? and display = ?', 'US', true)
15
+ countries.unshift(where('iso_code_2 = ?', 'US').first)
16
+
17
+ countries
18
+ end
19
+
20
+ end
21
+
11
22
  end
@@ -1,32 +1,20 @@
1
1
  class Individual < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
- require 'attr_encrypted'
5
-
6
4
  after_create :create_party
7
5
  after_save :save_party
8
6
  after_destroy :destroy_party
9
7
 
10
8
  has_one :party, :as => :business_party
11
9
 
12
- attr_encrypted :encrypted_ssn, :key => 'a secret key', :marshall => true
13
- alias_attribute :unencypted_ssn, :social_security_number
10
+ attr_encrypted :ssn, :key => Rails.application.config.erp_base_erp_svcs.encryption_key, :attribute => :encrypted_ssn
14
11
 
15
12
  def after_initialize
16
13
  self.salt ||= Digest::SHA256.hexdigest((Time.now.to_i * rand(5)).to_s)
17
14
  end
18
15
 
19
- def social_security_number=(ssn)
20
- self.ssn_last_four = ssn[-4..-1]
21
- self.encrypted_ssn = Individual.encrypt_encrypted_ssn(ssn)
22
- self.save
23
- end
24
-
25
- def social_security_number
26
- Individual.decrypt_encrypted_ssn(self.encrypted_ssn)
27
- end
28
-
29
- alias_method :ssn, :social_security_number
16
+ alias :social_security_number= :ssn=
17
+ alias :social_security_number :ssn
30
18
 
31
19
  def formatted_ssn_label
32
20
  (self.ssn_last_four.blank?) ? "" : "XXX-XX-#{self.ssn_last_four}"
@@ -48,11 +36,14 @@ class Individual < ActiveRecord::Base
48
36
  end
49
37
 
50
38
  def create_party
51
- pty = Party.new
52
- pty.description = [current_personal_title, current_first_name, current_last_name].join(' ').strip
53
- pty.business_party = self
54
- pty.save
55
- self.save
39
+ unless self.party
40
+ pty = Party.new
41
+ pty.description = [current_personal_title, current_first_name, current_last_name].join(' ').strip
42
+ pty.business_party = self
43
+ pty.save
44
+ self.party = pty
45
+ self.save
46
+ end
56
47
  end
57
48
 
58
49
  def save_party
@@ -1,10 +1,15 @@
1
1
  class Note < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
+ tracks_created_by_updated_by
5
+
4
6
  belongs_to :note_type
5
7
  belongs_to :noted_record, :polymorphic => true
6
8
  belongs_to :created_by, :class_name => 'Party', :foreign_key => 'created_by_id'
7
9
 
10
+ validates :content, presence: true
11
+ validates :note_type, presence: true
12
+
8
13
  def note_type_desc
9
14
  self.note_type.description
10
15
  end
@@ -13,4 +18,8 @@ class Note < ActiveRecord::Base
13
18
  (content.length > 20) ? "#{content[0..20]}..." : content
14
19
  end
15
20
 
21
+ def to_s
22
+ summary
23
+ end
24
+
16
25
  end
@@ -2,8 +2,10 @@ class NoteType < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
4
  acts_as_nested_set
5
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
5
6
  acts_as_erp_type
6
7
 
7
8
  belongs_to :note_type_record, :polymorphic => true
8
9
  has_many :notes
10
+
9
11
  end
@@ -1,32 +1,35 @@
1
1
  class Organization < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
-
4
- after_create :create_party
5
- after_save :save_party
6
- after_destroy :destroy_party
7
-
3
+
4
+ after_create :create_party
5
+ after_save :save_party
6
+ after_destroy :destroy_party
7
+
8
8
  has_one :party, :as => :business_party
9
9
 
10
10
  def create_party
11
- pty = Party.new
12
- pty.description = self.description
13
- pty.business_party = self
14
-
15
- pty.save
16
- self.save
11
+ unless self.party
12
+ pty = Party.new
13
+ pty.description = self.description
14
+ pty.business_party = self
15
+
16
+ pty.save
17
+ self.party = pty
18
+ self.save
19
+ end
17
20
  end
18
-
19
- def save_party
21
+
22
+ def save_party
20
23
  self.party.description = self.description
21
24
  self.party.save
22
- end
25
+ end
23
26
 
24
27
  def destroy_party
25
28
  if self.party
26
- self.party.destroy
29
+ self.party.destroy
27
30
  end
28
31
  end
29
-
32
+
30
33
  def to_label
31
34
  "#{description}"
32
35
  end
@@ -2,11 +2,14 @@ class Party < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
4
  has_notes
5
+ has_contacts
6
+ tracks_created_by_updated_by
5
7
 
6
- has_many :contacts, :dependent => :destroy
7
8
  has_many :created_notes, :class_name => 'Note', :foreign_key => 'created_by_id'
8
9
  belongs_to :business_party, :polymorphic => true
9
10
 
11
+ has_many :entity_party_roles, dependent: :destroy
12
+
10
13
  has_many :party_roles, :dependent => :destroy #role_types
11
14
  has_many :role_types, :through => :party_roles
12
15
 
@@ -15,9 +18,94 @@ class Party < ActiveRecord::Base
15
18
  attr_reader :relationships
16
19
  attr_writer :create_relationship
17
20
 
18
- # serialize ExtJs attributes
19
- is_json :custom_fields
20
-
21
+ class << self
22
+ # scope by dba organization
23
+ #
24
+ # @param dba_organization [Party, Array] dba organization to scope by or Array of dba organizations to
25
+ # scope by
26
+ #
27
+ # @return [ActiveRecord::Relation]
28
+ def scope_by_dba_organization(dba_organization)
29
+ joins("inner join party_relationships on party_relationships.role_type_id_to ='#{RoleType.iid('dba_org').id}'
30
+ and party_relationships.party_id_from = parties.id")
31
+ .where({party_relationships: {party_id_to: dba_organization}})
32
+ end
33
+
34
+ # Scopes parties by passed role types
35
+ #
36
+ # @param role_types [Array, RoleType] Array of RoleTypes to scope by
37
+ def with_role_types(role_types)
38
+ joins('inner join party_roles on party_roles.party_id = parties.id').where('party_roles.role_type_id' => role_types)
39
+ end
40
+
41
+ end
42
+
43
+ # helper method to get dba_organization related to this party
44
+ #
45
+ # @return [Party] DBA Organization
46
+ def dba_organization
47
+ find_related_parties_with_role('dba_org').first
48
+ end
49
+
50
+ # Get any child DBA Organizations related this party
51
+ #
52
+ # @param dba_orgs [Array] Array of current DBA Organizations to add to
53
+ # @return [Array] Child DBA Organizations
54
+ def child_dba_organizations(dba_orgs=[])
55
+ dba_org = RoleType.iid('dba_org')
56
+
57
+ PartyRelationship.joins('inner join parties on parties.id = party_relationships.party_id_from')
58
+ .joins('inner join party_roles on party_roles.party_id = party_relationships.party_id_from')
59
+ .where('party_id_to' => self.id)
60
+ .where('party_relationships.role_type_id_to' => dba_org)
61
+ .where('party_roles.role_type_id' => dba_org).each do |party_reln|
62
+
63
+ dba_orgs.push(party_reln.from_party)
64
+ if !dba_orgs.collect(&:id).include? party_reln.from_party.id
65
+ party_reln.from_party.child_dba_organizations(dba_orgs)
66
+ end
67
+
68
+ end
69
+
70
+ dba_orgs.uniq
71
+ end
72
+
73
+ # Get all parties that have a relationship to this party. If deep is passed then of those parties do the same
74
+ # all the way down the relationship chain
75
+ #
76
+ # @param parties [Array] Array of currently found related parties
77
+ # @return [Array] Array of related parties
78
+ def parties_in_relationships(parties=[], deep=false)
79
+ PartyRelationship.where('party_id_to' => self.id).each do |party_reln|
80
+
81
+ parties.push(party_reln.from_party) unless parties.include?(party_reln.from_party)
82
+ if deep and !parties.collect(&:id).include? party_reln.from_party.id
83
+ party_reln.from_party.parties_in_relationships(parties, deep)
84
+ else
85
+ parties
86
+ end
87
+
88
+ end
89
+
90
+ parties.uniq
91
+ end
92
+
93
+ # Get any parent DBA Organizations related this party
94
+ #
95
+ # @param dba_orgs [Array] Array of current DBA Organizations to add to
96
+ # @return [Array] Parent DBA Organizations
97
+ def parent_dba_organizations(dba_orgs=[])
98
+ PartyRelationship.
99
+ where('party_id_from = ?', id).
100
+ where('role_type_id_to' => RoleType.iid('dba_org')).each do |party_reln|
101
+
102
+ dba_orgs.push(party_reln.to_party)
103
+ party_reln.to_party.parent_dba_organizations(dba_orgs)
104
+ end
105
+
106
+ dba_orgs.uniq
107
+ end
108
+
21
109
  # Gathers all party relationships that contain this particular party id
22
110
  # in either the from or to side of the relationship.
23
111
  def relationships
@@ -32,10 +120,16 @@ class Party < ActiveRecord::Base
32
120
  @relationships ||= PartyRelationship.where('party_id_from = ?', id)
33
121
  end
34
122
 
123
+ def find_related_parties_with_role(role_type_iid)
124
+ Party.joins(:party_roles).joins("inner join party_relationships on (party_id_from = #{id} and parties.id = party_relationships.party_id_to)")
125
+ .where(PartyRole.arel_table[:role_type_id].eq(RoleType.iid(role_type_iid).id))
126
+ .where(Party.arel_table[:id].not_eq(id))
127
+ end
128
+
35
129
  def find_relationships_by_type(relationship_type_iid)
36
130
  PartyRelationship.includes(:relationship_type).
37
- where('party_id_from = ? or party_id_to = ?', id, id).
38
- where('relationship_types.internal_identifier' => relationship_type_iid.to_s)
131
+ where('party_id_from = ? or party_id_to = ?', id, id).
132
+ where('relationship_types.internal_identifier' => relationship_type_iid.to_s)
39
133
  end
40
134
 
41
135
  # Creates a new PartyRelationship for this particular
@@ -60,40 +154,23 @@ class Party < ActiveRecord::Base
60
154
  PartyRelationship.destroy_all("party_id_from = #{id} or party_id_to = #{id}")
61
155
  end
62
156
 
157
+ def add_role_type(role)
158
+ role = role.is_a?(RoleType) ? role : RoleType.iid(role)
159
+
160
+ PartyRole.create(party: self, role_type: role)
161
+ end
162
+
63
163
  def has_role_type?(*passed_roles)
64
164
  result = false
65
165
  passed_roles.flatten!
66
166
  passed_roles.each do |role|
67
167
  role_iid = role.is_a?(RoleType) ? role.internal_identifier : role.to_s
68
- self.role_types.each do |this_role|
69
- result = true if (this_role.internal_identifier == role_iid)
70
- break if result
71
- end
72
- break if result
73
- end
74
- result
75
- end
76
168
 
77
- def has_phone_number?(phone_number)
78
- result = nil
79
- self.contacts.each do |c|
80
- if c.contact_mechanism_type == 'PhoneNumber'
81
- if c.contact_mechanism.phone_number == phone_number
82
- result = true
83
- end
169
+ PartyRole.where(party_id: self.id).each do |party_role|
170
+ result = true if (party_role.role_type.internal_identifier == role_iid)
171
+ break if result
84
172
  end
85
- end
86
- result
87
- end
88
173
 
89
- def has_zip_code?(zip)
90
- result = nil
91
- self.contacts.each do |c|
92
- if c.contact_mechanism_type == 'PostalAddress'
93
- if c.contact_mechanism.zip == zip
94
- result = true
95
- end
96
- end
97
174
  end
98
175
  result
99
176
  end
@@ -107,207 +184,35 @@ class Party < ActiveRecord::Base
107
184
  "#{description}"
108
185
  end
109
186
 
110
- #************************************************************************************************
111
- #** Contact Methods
112
- #************************************************************************************************
113
-
114
- def primary_phone_number
115
- contact_mechanism = nil
116
-
117
- contact = self.get_primary_contact(PhoneNumber)
118
- contact_mechanism = contact.contact_mechanism unless contact.nil?
119
-
120
- contact_mechanism
121
- end
122
-
123
- alias primary_phone primary_phone_number
124
-
125
- def primary_phone_number=(phone_number)
126
- self.set_primary_contact(PhoneNumber, phone_number)
127
- end
128
-
129
- alias primary_phone= primary_phone_number=
130
-
131
- def primary_email_address
132
- contact_mechanism = nil
133
-
134
- contact = self.get_primary_contact(EmailAddress)
135
- contact_mechanism = contact.contact_mechanism unless contact.nil?
136
-
137
- contact_mechanism
138
- end
139
-
140
- alias primary_email primary_email_address
141
-
142
- def primary_email_address=(email_address)
143
- self.set_primary_contact(EmailAddress, email_address)
144
- end
145
-
146
- alias primary_email= primary_email_address=
147
-
148
- def primary_postal_address
149
- contact_mechanism = nil
150
-
151
- contact = self.get_primary_contact(PostalAddress)
152
- contact_mechanism = contact.contact_mechanism unless contact.nil?
153
-
154
- contact_mechanism
155
- end
156
-
157
- alias primary_address primary_postal_address
158
-
159
- def primary_postal_address=(postal_address)
160
- self.set_primary_contact(PostalAddress, postal_address)
161
- end
162
-
163
- alias primary_address= primary_postal_address=
164
-
165
- def set_primary_contact(contact_mechanism_class, contact_mechanism_instance)
166
- # set is_primary to false for any current primary contacts of this type
167
- primary_contact_mechanism = get_primary_contact(contact_mechanism_class)
168
- if primary_contact_mechanism
169
- primary_contact_mechanism.is_primary = false
170
- primary_contact_mechanism.save
171
- end
172
-
173
- contact_mechanism_instance.is_primary = true
174
- contact_mechanism_instance.save
175
-
176
- contact_mechanism_instance
177
- end
178
-
179
- def get_primary_contact(contact_mechanism_class)
180
- table_name = contact_mechanism_class.name.tableize
181
-
182
- self.contacts.joins("inner join #{table_name} on #{table_name}.id = contact_mechanism_id and contact_mechanism_type = '#{contact_mechanism_class.name}'")
183
- .where('contacts.is_primary = ?', true).readonly(false).first
184
- end
185
-
186
- def find_contact_mechanism_with_purpose(contact_mechanism_class, contact_purpose)
187
- contact = self.find_contact_with_purpose(contact_mechanism_class, contact_purpose)
188
-
189
- contact.contact_mechanism unless contact.nil?
190
- end
191
-
192
- def find_contact_with_purpose(contact_mechanism_class, contact_purpose)
193
- #if a symbol or string was passed get the model
194
- unless contact_purpose.is_a? ContactPurpose
195
- contact_purpose = ContactPurpose.find_by_internal_identifier(contact_purpose.to_s)
196
- end
197
-
198
- self.find_contact(contact_mechanism_class, nil, [contact_purpose])
199
- end
200
-
201
- def find_all_contacts_by_contact_mechanism(contact_mechanism_class)
202
- table_name = contact_mechanism_class.name.tableize
203
-
204
- contacts = self.contacts.joins("inner join #{table_name} on #{table_name}.id = contact_mechanism_id and contact_mechanism_type = '#{contact_mechanism_class.name}'")
205
-
206
- contacts.collect(&:contact_mechanism)
207
- end
208
-
209
- def find_contact(contact_mechanism_class, contact_mechanism_args={}, contact_purposes=[])
210
- table_name = contact_mechanism_class.name.tableize
211
-
212
- query = self.contacts.joins("inner join #{table_name} on #{table_name}.id = contact_mechanism_id and contact_mechanism_type = '#{contact_mechanism_class.name}'
213
- inner join contact_purposes_contacts on contact_purposes_contacts.contact_id = contacts.id
214
- and contact_purposes_contacts.contact_purpose_id in (#{contact_purposes.collect { |item| item.attributes["id"] }.join(',')})")
215
-
216
- contact_mechanism_args.each do |key, value|
217
- next if key == 'updated_at' or key == 'created_at' or key == 'id' or key == 'is_primary'
218
- query = query.where("#{table_name}.#{key} = ?", value) unless value.nil?
219
- end unless contact_mechanism_args.nil?
220
-
221
- query.first
222
- end
223
-
224
- # looks for contacts matching on value and purpose
225
- # if a contact exists, it updates, if not, it adds it
226
- def add_contact(contact_mechanism_class, contact_mechanism_args={}, contact_purposes=[])
227
- is_primary = contact_mechanism_args['is_primary']
228
- contact_purposes = [contact_purposes] if !contact_purposes.kind_of?(Array) # gracefully handle a single purpose not in an array
229
-
230
- contact_mechanism_args.delete_if { |k, v| ['created_at', 'updated_at', 'is_primary'].include? k.to_s }
231
- contact_mechanism = contact_mechanism_class.new(contact_mechanism_args)
232
- contact_mechanism.contact.party = self
233
- contact_mechanism.contact.contact_purposes = contact_purposes
234
- contact_mechanism.contact.save
235
- contact_mechanism.save
236
-
237
- set_primary_contact(contact_mechanism_class, contact_mechanism) if is_primary
238
-
239
- contact_mechanism
240
- end
241
-
242
- # tries to update contact by purpose
243
- # if contact doesn't exist, it adds it
244
- def update_or_add_contact_with_purpose(contact_mechanism_class, contact_purpose, contact_mechanism_args)
245
- contact_mechanism = update_contact_with_purpose(contact_mechanism_class, contact_purpose, contact_mechanism_args)
246
-
247
- unless contact_mechanism
248
- contact_mechanism = add_contact(contact_mechanism_class, contact_mechanism_args, [contact_purpose])
249
- end
250
-
251
- contact_mechanism
252
- end
253
-
254
- # looks for a contact matching on purpose
255
- # if it exists, it updates it, if not returns false
256
- def update_contact_with_purpose(contact_mechanism_class, contact_purpose, contact_mechanism_args)
257
- contact = find_contact_with_purpose(contact_mechanism_class, contact_purpose)
258
- contact.nil? ? false : update_contact(contact_mechanism_class, contact, contact_mechanism_args)
259
- end
260
-
261
- def update_contact(contact_mechanism_class, contact, contact_mechanism_args)
262
- set_primary_contact(contact_mechanism_class, contact.contact_mechanism) if contact_mechanism_args[:is_primary] == true
263
-
264
- contact_mechanism_class.update(contact.contact_mechanism, contact_mechanism_args)
265
-
266
- contact.contact_mechanism
267
- end
268
-
269
- def get_contact_by_method(m)
270
- method_name = m.split('_')
271
- return nil if method_name.size < 3 or method_name.size > 4
272
- # handles 1 or 2 segment contact purposes (i.e. home or employment_offer)
273
- # contact mechanism must be 2 segments, (i.e. email_address, postal_address, phone_number)
274
- if method_name.size == 4
275
- purpose = method_name[0] + '_' + method_name[1]
276
- klass = method_name[2] + '_' + method_name[3]
277
- else
278
- purpose = method_name[0]
279
- klass = method_name[1] + '_' + method_name[2]
280
- end
281
-
282
- #constantize klass to make sure it exists and is loaded
283
- begin
284
- klass_const = klass.camelize.constantize
285
- contact_purpose = ContactPurpose.find_by_internal_identifier(purpose)
286
- if contact_purpose.nil?
287
- return nil
187
+ # convert party record to hash of data
188
+ #
189
+ def to_data_hash
190
+ data = to_hash(only: [
191
+ :id,
192
+ :description,
193
+ :created_at,
194
+ :updated_at
195
+ ],
196
+ business_party_type: business_party.class.name
197
+ )
198
+
199
+ # get business party data
200
+ if business_party
201
+ if business_party.is_a?(Individual)
202
+ data.merge!({
203
+ first_name: business_party.current_first_name,
204
+ last_name: business_party.current_last_name,
205
+ middle_name: business_party.current_middle_name,
206
+ gender: business_party.gender
207
+ })
288
208
  else
289
- find_contact_mechanism_with_purpose(klass_const, contact_purpose)
209
+ data.merge!({
210
+ tax_id_number: business_party.tax_id_number
211
+ })
290
212
  end
291
- rescue NameError
292
- return nil
293
213
  end
294
214
 
215
+ data
295
216
  end
296
217
 
297
- def respond_to?(m, include_private_methods = false)
298
- (super ? true : get_contact_by_method(m.to_s)) rescue super
299
- end
300
-
301
- def method_missing(m, *args, &block)
302
- if self.respond_to?(m)
303
- value = get_contact_by_method(m.to_s)
304
- (value.nil?) ? super : (return value)
305
- else
306
- super
307
- end
308
- end
309
-
310
- #************************************************************************************************
311
- #** End
312
- #************************************************************************************************
313
218
  end