amo_crm 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/CHANGELOG.md +22 -0
  6. data/Gemfile +4 -0
  7. data/Guardfile +29 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +1 -0
  10. data/Rakefile +14 -0
  11. data/amo_crm.gemspec +41 -0
  12. data/dump_amocrm_account.rb +7 -0
  13. data/lib/amo_crm.rb +31 -0
  14. data/lib/amo_crm/client.rb +98 -0
  15. data/lib/amo_crm/client/error.rb +18 -0
  16. data/lib/amo_crm/client/errors.rb +16 -0
  17. data/lib/amo_crm/entities.rb +14 -0
  18. data/lib/amo_crm/entities/account.rb +7 -0
  19. data/lib/amo_crm/entities/attachment_document.rb +16 -0
  20. data/lib/amo_crm/entities/attribute.rb +71 -0
  21. data/lib/amo_crm/entities/attribute_metadata.rb +38 -0
  22. data/lib/amo_crm/entities/barcode.rb +19 -0
  23. data/lib/amo_crm/entities/base.rb +5 -0
  24. data/lib/amo_crm/entities/collection.rb +12 -0
  25. data/lib/amo_crm/entities/common.rb +15 -0
  26. data/lib/amo_crm/entities/common_object.rb +27 -0
  27. data/lib/amo_crm/entities/company.rb +30 -0
  28. data/lib/amo_crm/entities/company_concern.rb +20 -0
  29. data/lib/amo_crm/entities/consignment.rb +22 -0
  30. data/lib/amo_crm/entities/contact.rb +29 -0
  31. data/lib/amo_crm/entities/contract.rb +2 -0
  32. data/lib/amo_crm/entities/country.rb +10 -0
  33. data/lib/amo_crm/entities/custom_entity.rb +18 -0
  34. data/lib/amo_crm/entities/custom_entity_metadata.rb +36 -0
  35. data/lib/amo_crm/entities/custom_field.rb +6 -0
  36. data/lib/amo_crm/entities/custom_field_definition.rb +13 -0
  37. data/lib/amo_crm/entities/custom_field_value.rb +5 -0
  38. data/lib/amo_crm/entities/custom_fields.rb +24 -0
  39. data/lib/amo_crm/entities/custom_fields_definition.rb +4 -0
  40. data/lib/amo_crm/entities/customer_order.rb +51 -0
  41. data/lib/amo_crm/entities/customer_order_position.rb +22 -0
  42. data/lib/amo_crm/entities/embedded_entity_metadata.rb +18 -0
  43. data/lib/amo_crm/entities/error.rb +13 -0
  44. data/lib/amo_crm/entities/feature.rb +23 -0
  45. data/lib/amo_crm/entities/good.rb +34 -0
  46. data/lib/amo_crm/entities/good_folder.rb +10 -0
  47. data/lib/amo_crm/entities/good_ref.rb +12 -0
  48. data/lib/amo_crm/entities/image.rb +21 -0
  49. data/lib/amo_crm/entities/images.rb +10 -0
  50. data/lib/amo_crm/entities/lead.rb +28 -0
  51. data/lib/amo_crm/entities/my_company.rb +12 -0
  52. data/lib/amo_crm/entities/page.rb +5 -0
  53. data/lib/amo_crm/entities/price.rb +15 -0
  54. data/lib/amo_crm/entities/price_type.rb +13 -0
  55. data/lib/amo_crm/entities/sale_price.rb +18 -0
  56. data/lib/amo_crm/entities/sale_prices.rb +10 -0
  57. data/lib/amo_crm/entities/slot.rb +10 -0
  58. data/lib/amo_crm/entities/stock_to.rb +33 -0
  59. data/lib/amo_crm/entities/warehouse.rb +15 -0
  60. data/lib/amo_crm/entities/workflow.rb +11 -0
  61. data/lib/amo_crm/entities/workflow_state.rb +8 -0
  62. data/lib/amo_crm/entities/xml_fix.rb +14 -0
  63. data/lib/amo_crm/errors.rb +1 -0
  64. data/lib/amo_crm/resources.rb +18 -0
  65. data/lib/amo_crm/resources/account.rb +30 -0
  66. data/lib/amo_crm/resources/base.rb +149 -0
  67. data/lib/amo_crm/resources/companies.rb +27 -0
  68. data/lib/amo_crm/resources/contacts.rb +23 -0
  69. data/lib/amo_crm/resources/custom_entity_metadata.rb +18 -0
  70. data/lib/amo_crm/resources/custom_field.rb +28 -0
  71. data/lib/amo_crm/resources/embedded_entity_metadata.rb +20 -0
  72. data/lib/amo_crm/resources/embedded_entity_metadata_indexed.rb +7 -0
  73. data/lib/amo_crm/resources/indexed.rb +89 -0
  74. data/lib/amo_crm/resources/leads.rb +31 -0
  75. data/lib/amo_crm/resources/stock.rb +36 -0
  76. data/lib/amo_crm/resources/subresource.rb +21 -0
  77. data/lib/amo_crm/resources/where_filter.rb +26 -0
  78. data/lib/amo_crm/response.rb +7 -0
  79. data/lib/amo_crm/universe.rb +44 -0
  80. data/lib/amo_crm/version.rb +3 -0
  81. data/scripts/rest.sh +25 -0
  82. data/spec/fixtures/302.raw +15 -0
  83. data/spec/fixtures/400.raw +8 -0
  84. data/spec/fixtures/401.html +1 -0
  85. data/spec/fixtures/401_2.html +1 -0
  86. data/spec/fixtures/405.raw +9 -0
  87. data/spec/fixtures/500.raw +8 -0
  88. data/spec/fixtures/502.raw +8 -0
  89. data/spec/fixtures/Consignment_list_0.raw +14 -0
  90. data/spec/fixtures/Consignment_list_1000.raw +14 -0
  91. data/spec/fixtures/Country_list.raw +14 -0
  92. data/spec/fixtures/CustomEntityMetadata_list.raw +14 -0
  93. data/spec/fixtures/CustomEntity_list.raw +14 -0
  94. data/spec/fixtures/CustomEntity_list_bad_chars.raw +17 -0
  95. data/spec/fixtures/EmbeddedEntityMetadata_list.raw +15 -0
  96. data/spec/fixtures/Feature_list.raw +14 -0
  97. data/spec/fixtures/Feature_list_1000.raw +14 -0
  98. data/spec/fixtures/Good_WithManyAttributes.raw +13 -0
  99. data/spec/fixtures/Good_e932ebe1-2e22-11e4-9406-002590a28eca.raw +12 -0
  100. data/spec/fixtures/Good_eb77ad57-2e22-11e4-4030-002590a28eca.raw +12 -0
  101. data/spec/fixtures/Goods_list.raw +14 -0
  102. data/spec/fixtures/Metadata_list.raw +14 -0
  103. data/spec/fixtures/PriceType_list.raw +14 -0
  104. data/spec/fixtures/Stock.raw +11 -0
  105. data/spec/fixtures/Stock_showConsignments.raw +11 -0
  106. data/spec/fixtures/Uom_list.raw +14 -0
  107. data/spec/fixtures/Warehouse_list.raw +14 -0
  108. data/spec/fixtures/Workflow_list.raw +15 -0
  109. data/spec/fixtures/attribute_boolean.xml +6 -0
  110. data/spec/fixtures/attribute_dictionary.xml +5 -0
  111. data/spec/fixtures/attribute_double.xml +6 -0
  112. data/spec/fixtures/attribute_file.xml +12 -0
  113. data/spec/fixtures/attribute_long.xml +6 -0
  114. data/spec/fixtures/attribute_text.xml +5 -0
  115. data/spec/fixtures/attribute_time.xml +6 -0
  116. data/spec/fixtures/attribute_url.xml +6 -0
  117. data/spec/fixtures/bad_chars.xml +6 -0
  118. data/spec/fixtures/customer_order.xml +28 -0
  119. data/spec/fixtures/good_with_attributes.raw +12 -0
  120. data/spec/fixtures/good_with_image.xml +39 -0
  121. data/spec/fixtures/resource_forbidden.raw +9 -0
  122. data/spec/fixtures/wrong_password.raw +9 -0
  123. data/spec/fixtures/wrong_type.raw +70 -0
  124. data/spec/fixtures/wrong_user.raw +9 -0
  125. data/spec/lib/amocrm/client/errors_spec.rb +102 -0
  126. data/spec/lib/amocrm/entities/attribute_metadata_spec.rb +30 -0
  127. data/spec/lib/amocrm/entities/attribute_spec.rb +36 -0
  128. data/spec/lib/amocrm/entities/country_spec.rb +25 -0
  129. data/spec/lib/amocrm/entities/custom_entity_metadata_spec.rb +34 -0
  130. data/spec/lib/amocrm/entities/custom_entity_spec.rb +34 -0
  131. data/spec/lib/amocrm/entities/customer_order_position_spec.rb +35 -0
  132. data/spec/lib/amocrm/entities/customer_order_spec.rb +58 -0
  133. data/spec/lib/amocrm/entities/good_spec.rb +55 -0
  134. data/spec/lib/amocrm/resources/base_spec.rb +61 -0
  135. data/spec/lib/amocrm/resources/countries_spec.rb +22 -0
  136. data/spec/lib/amocrm/resources/custom_entity_metadata_spec.rb +13 -0
  137. data/spec/lib/amocrm/resources/embedded_entity_metadata_indexed_spec.rb +20 -0
  138. data/spec/lib/amocrm/resources/embedded_entity_metadata_spec.rb +11 -0
  139. data/spec/lib/amocrm/resources/good_folders_spec.rb +17 -0
  140. data/spec/lib/amocrm/resources/indexed_spec.rb +61 -0
  141. data/spec/lib/amocrm/resources/stock_spec.rb +63 -0
  142. data/spec/lib/amocrm/resources/subresource_spec.rb +13 -0
  143. data/spec/lib/amocrm/resources/warehouses_spec.rb +20 -0
  144. data/spec/lib/amocrm/resources/workflows_spec.rb +21 -0
  145. data/spec/lib/amocrm/resources_spec.rb +10 -0
  146. data/spec/lib/amocrm/universe_spec.rb +53 -0
  147. data/spec/lib/amocrm_spec.rb +8 -0
  148. data/spec/spec_helper.rb +106 -0
  149. data/spec/support/resource.rb +72 -0
  150. metadata +500 -0
@@ -0,0 +1,38 @@
1
+ module AmoCRM::Entities
2
+ # https://online.moysklad.ru/exchange/rest/ms/xml/Metadata/list
3
+ class AttributeMetadata < Base
4
+ include CommonObject
5
+
6
+ tag 'attributeMetadata'
7
+
8
+ # ID_CUSTOM - элемент из dictionary
9
+ # TEXT
10
+ # STRING
11
+ attribute :attrType, String
12
+ attribute :entityMetadataUuid, String
13
+ attribute :feature, Boolean
14
+ attribute :position, Integer
15
+ attribute :required, Boolean
16
+ attribute :dictionaryMetadataUuid, String
17
+
18
+ def is_dictionary?
19
+ attrType == 'ID_CUSTOM'
20
+ end
21
+
22
+ # Если это свойство типа ID_CUSTOM, то возвращается пользовательский справочник
23
+ #
24
+ # @return AmoCRM::Entities::CustomEntityMetadata
25
+ def dictionatyMetadata universe
26
+ raise "Это свойства не типа справочник" unless dictionaryMetadataUuid
27
+ universe.custom_entity_metadata.find dictionaryMetadataUuid
28
+ end
29
+
30
+ # Справочник к которому принадлежит это ссвойство
31
+ #
32
+ # @return AmoCRM::Entities::EmbeddedEntityMetadata
33
+ def entityMetadata universe
34
+ universe.embedded_entity_metadata.find entityMetadataUuid
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ module AmoCRM::Entities
2
+ class Barcode < Base
3
+ include HappyMapper
4
+ include AmoCRM::Entities::XmlFix
5
+
6
+ tag 'barcode'
7
+
8
+ attribute :barcode, String
9
+ attribute :barcodeType, String
10
+
11
+ attribute :accountUuid, String
12
+ attribute :accountId, String
13
+ attribute :uuid, String
14
+ attribute :groupUuid, String
15
+ attribute :ownerUuid, String
16
+
17
+ attribute :shared, Boolean
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ require 'hashie'
2
+ module AmoCRM::Entities
3
+ class Base < Hashie::Mash
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module AmoCRM::Entities
2
+ class Collection < Base
3
+ # Типовое количество элементов которое возвращает мойсклад
4
+ DEFAULT_COUNT = 1000
5
+ include HappyMapper
6
+
7
+ attribute :total, Integer
8
+ attribute :start, Integer
9
+ attribute :count, Integer
10
+
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module AmoCRM::Entities::Common
2
+ extend ::ActiveSupport::Concern
3
+
4
+ included do
5
+ include HappyMapper
6
+
7
+ attribute :readMode, String
8
+ attribute :changeMode, String
9
+
10
+ element :accountUuid, String
11
+ element :accountId, String
12
+ element :uuid, String
13
+ end
14
+
15
+ end
@@ -0,0 +1,27 @@
1
+ module AmoCRM::Entities::CommonObject
2
+ extend ActiveSupport::Concern
3
+
4
+ # Используется в Good
5
+ # https://online.moysklad.ru/exchange/rest/ms/xml/Good/list
6
+ #
7
+ # В Metadata
8
+ # https://online.moysklad.ru/exchange/rest/ms/xml/Metadata/list
9
+ #
10
+ # Во Feature
11
+ # https://online.moysklad.ru/exchange/rest/ms/xml/Feature/list
12
+ #
13
+ # CustomerOrder
14
+ # https://online.moysklad.ru/exchange/rest/ms/xml/CustomerOrder/list
15
+ #
16
+ included do
17
+ include AmoCRM::Entities::Common
18
+
19
+ attribute :updated, Time
20
+ attribute :updatedBy, String
21
+
22
+ attribute :name, String
23
+
24
+ element :externalcode, String
25
+ element :description, String
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ module AmoCRM::Entities
2
+ class Company
3
+ include Virtus.model
4
+ attribute :name, String
5
+ attribute :request_id, Integer
6
+ attribute :date_create, Time
7
+ attribute :last_modified, Time
8
+ attribute :responsible_user_id, Integer
9
+ attribute :linked_leads_id, Array[Integer]
10
+ attribute :tags, Array[String]
11
+ attribute :company_name, String
12
+
13
+ attribute :custom_fields, Array[CustomFieldValue]
14
+
15
+ def to_s
16
+ as_json.to_s
17
+ end
18
+
19
+ def attributes_for_update
20
+ {
21
+ id: id,
22
+ last_modified: last_modified,
23
+ request_id: request_id,
24
+ name: name,
25
+ company_name: company_name,
26
+ custom_fields: custom_fields
27
+ }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ module AmoCRM::Entities::CompanyConcern
2
+ extend ActiveSupport::Concern
3
+ included do
4
+ include HappyMapper
5
+ include AmoCRM::Entities::CommonObject
6
+
7
+ attribute :created, Time
8
+ attribute :archived, HappyMapper::Boolean
9
+
10
+ attribute :companyType, String
11
+
12
+ attribute :discount, Float
13
+ attribute :autoDiscount, Float
14
+ attribute :discountCardNumber, String
15
+ attribute :discountCorrection, Float
16
+
17
+ element :code, String
18
+
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ module AmoCRM::Entities
2
+ # https://online.moysklad.ru/exchange/rest/ms/xml/Consignment/list
3
+ class Consignment < Base
4
+ include Common
5
+
6
+ tag 'consignment'
7
+
8
+ attribute :updated, Time
9
+ attribute :updatedBy, String
10
+
11
+ attribute :name, String
12
+
13
+ attribute :goodUuid, String
14
+ attribute :isDefault, Boolean
15
+
16
+ attribute :archived, Boolean
17
+
18
+ element :externalcode, String
19
+
20
+ has_one :feature, AmoCRM::Entities::Feature
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ module AmoCRM::Entities
2
+ class Contact
3
+ include Virtus.model
4
+ attribute :name, String
5
+ attribute :request_id, Integer
6
+ attribute :date_create, Time
7
+ attribute :last_modified, Time
8
+ attribute :responsible_user_id, Integer
9
+ attribute :linked_leads_id, Array[Integer]
10
+ attribute :tags, Array[String]
11
+ attribute :company_name, String
12
+
13
+ attribute :custom_fields, Array[CustomFieldValue]
14
+
15
+ def attributes_for_update
16
+ {
17
+ name: name,
18
+ request_id: request_id,
19
+ date_create: date_create.to_i,
20
+ last_modified: last_modified.to_i,
21
+ responsible_user_id: responsible_user_id,
22
+ linked_leads_id: linked_leads_id,
23
+ tags: tags,
24
+ company_name: company_name,
25
+ custom_fields: custom_fields.as_json
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,2 @@
1
+ # https://online.moysklad.ru/exchange/rest/ms/xml/Contract/list
2
+
@@ -0,0 +1,10 @@
1
+ module AmoCRM::Entities
2
+ class Country < Base
3
+ include CommonObject
4
+ include AmoCRM::Entities::XmlFix
5
+
6
+ tag 'country'
7
+
8
+ element :code, String
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ # https://online.moysklad.ru/exchange/rest/ms/xml/CustomEntity/list
2
+ # Элемент пользовательского справочника
3
+ # (значения перечисляемых свойств)
4
+ module AmoCRM::Entities
5
+ class CustomEntity < Base
6
+ include CommonObject
7
+ include XmlFix
8
+
9
+ tag 'customEntity'
10
+
11
+ attribute :entityMetadataUuid, String
12
+
13
+ def entityMetadata universe
14
+ universe.custom_entity_metadata.find entityMetadataUuid
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ # https://online.moysklad.ru/exchange/rest/ms/xml/CustomEntityMetadata/list
2
+ #
3
+ # Пользовательский справочник
4
+ #
5
+ module AmoCRM::Entities
6
+ class CustomEntityMetadata < Base
7
+ include CommonObject
8
+ include XmlFix
9
+
10
+ tag 'customEntityMetadata'
11
+
12
+ attribute :uniqueCode, Boolean
13
+ attribute :codeValueType, Integer
14
+ attribute :independentNameGenerator, Boolean
15
+
16
+ attribute :partialReserve, Boolean
17
+
18
+ attribute :editOnlyByAuthor, Boolean
19
+
20
+ attribute :noEditFromOtherPlaceSource, Boolean
21
+
22
+ attribute :noApplicableFromOtherPlaceSource, Boolean
23
+
24
+ attribute :noEditFromOtherPlaceTarget, Boolean
25
+
26
+ attribute :noApplicableFromOtherPlaceTarget, Boolean
27
+
28
+ # Список перечисляемых значений данного справочника
29
+ #
30
+ # @return [Array[CustomEntity]]
31
+ def entities universe
32
+ universe.custom_entities.where entityMetadataUuid: uuid
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module AmoCRM::Entities
2
+ class CustomFielde < Base
3
+ attribute :id, Integer
4
+ attribute :value
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module AmoCRM::Entities
2
+ class CustomField < Base
3
+ attribute :id, Integer
4
+ attribute :name, String
5
+ attribute :code, String # PHONE, EMAIL, WEB, ADDRESS
6
+ attribute :multiple, String # Y/N
7
+ attribute :type_id, Integer
8
+ attribute :disabled, Integer # 0/1
9
+ attribute :sort, Integer
10
+ attribute :enums, Hash # {"450999"=>"WORK", "451001"=>"WORKDD", "451003"=>"MOB", "451005"=>"FAX", "451007"=>"HOME", "451009"=>"OTHER"}}
11
+ attribute :values, Array[CustomFieldValue]
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module AmoCRM::Entities
2
+ class CustomFieldValue < Base
3
+ attribute :value, String
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ require 'hashie'
2
+
3
+ module AmoCRM
4
+ class CustomFields < Hashie::Mash
5
+ def as_json
6
+ map do |id, value|
7
+ values = Array(value).map { |value|
8
+ if value.is_a? Hash
9
+ value.map do |k, v|
10
+ {
11
+ value: v,
12
+ enum: k,
13
+ }
14
+ end
15
+ else
16
+ { value: value }
17
+ end
18
+ }.flatten
19
+
20
+ { id: id, values: values }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module AmoCRM
2
+ class CustomFields
3
+ end
4
+ end
@@ -0,0 +1,51 @@
1
+ module AmoCRM::Entities
2
+ # Пример:
3
+ # https://support.moysklad.ru/hc/ru/articles/203402923-Пример-загрузки-заказа-покупателя-через-REST-API
4
+ #
5
+ class CustomerOrder < Base
6
+ include CommonObject
7
+ include XmlFix
8
+
9
+ tag 'customerOrder'
10
+
11
+ attribute :created, Time
12
+ attribute :createdBy, String
13
+
14
+ attribute :stateUuid, String
15
+
16
+ attribute :reservedSum, Float
17
+
18
+ attribute :sourceStoreUuid, String
19
+ attribute :sourceAccountUuid, String
20
+ attribute :sourceAgentUuid, String
21
+
22
+ attribute :targetAgentUuid, String
23
+ attribute :targetAccountUuid, String
24
+
25
+ attribute :applicable, Boolean
26
+ attribute :moment, Time
27
+
28
+ attribute :payerVat, Boolean
29
+
30
+ attribute :consignmentUuid, String
31
+
32
+ attribute :rate, Float
33
+
34
+ attribute :vatIncluded, Boolean
35
+ attribute :name, String
36
+
37
+ element :sum, AmoCRM::Entities::Price, tag: :sum
38
+
39
+ element :deleted, Time
40
+
41
+ has_many :customerOrderPosition, AmoCRM::Entities::CustomerOrderPosition
42
+
43
+ def state universe
44
+ cache :customer_order_states, universe do
45
+ fail "No stateUuid in CustomerOrder #{uuid}" unless stateUuid
46
+ workflow = universe.workflows.findWhere name: 'CustomerOrder'
47
+ workflow.states.find { |s| s.uuid == stateUuid }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ module AmoCRM::Entities
2
+ class CustomerOrderPosition < Base
3
+ include HappyMapper
4
+ include XmlFix
5
+
6
+ tag 'customerOrderPosition'
7
+
8
+ attribute :vat, Integer
9
+ attribute :goodUuid, String
10
+ attribute :consignmentUuid, String
11
+ attribute :quantity, Float
12
+ attribute :discount, Float
13
+ attribute :consignmentUuid, String
14
+
15
+ element :deleted, Time
16
+
17
+ element :basePrice, AmoCRM::Entities::Price, tag: :basePrice
18
+ element :price, AmoCRM::Entities::Price, tag: :price
19
+ element :reserve, Float
20
+ end
21
+
22
+ end
@@ -0,0 +1,18 @@
1
+ module AmoCRM::Entities
2
+ # https://online.moysklad.ru/exchange/rest/ms/xml/Metadata/list
3
+ class EmbeddedEntityMetadata < Base
4
+ include CommonObject
5
+
6
+ tag 'embeddedEntityMetadata'
7
+
8
+ attribute :uniqueCode, Boolean
9
+ attribute :codeValueType, Integer
10
+ attribute :independentNameGenerator, Boolean
11
+ attribute :partialReserve, Boolean
12
+
13
+ has_many :attributeMetadata, AttributeMetadata
14
+
15
+ element :code, String
16
+ end
17
+ end
18
+