moysklad 0.0.2 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +2 -0
  4. data/Guardfile +5 -0
  5. data/Rakefile +6 -0
  6. data/lib/moysklad/client.rb +1 -1
  7. data/lib/moysklad/client/errors.rb +6 -4
  8. data/lib/moysklad/entities.rb +5 -0
  9. data/lib/moysklad/entities/attribute.rb +27 -2
  10. data/lib/moysklad/entities/attribute_metadata.rb +27 -0
  11. data/lib/moysklad/entities/base.rb +10 -0
  12. data/lib/moysklad/entities/common.rb +0 -1
  13. data/lib/moysklad/entities/custom_entity.rb +18 -0
  14. data/lib/moysklad/entities/custom_entity_metadata.rb +35 -0
  15. data/lib/moysklad/entities/customer_order.rb +4 -0
  16. data/lib/moysklad/entities/customer_order_position.rb +1 -0
  17. data/lib/moysklad/entities/embedded_entity_metadata.rb +2 -0
  18. data/lib/moysklad/entities/feature.rb +2 -3
  19. data/lib/moysklad/entities/good.rb +12 -9
  20. data/lib/moysklad/entities/good_folder.rb +9 -0
  21. data/lib/moysklad/entities/price.rb +1 -1
  22. data/lib/moysklad/entities/xml_fix.rb +9 -5
  23. data/lib/moysklad/resources.rb +7 -11
  24. data/lib/moysklad/resources/base.rb +11 -2
  25. data/lib/moysklad/resources/custom_entity_metadata.rb +18 -0
  26. data/lib/moysklad/resources/indexed.rb +56 -46
  27. data/lib/moysklad/resources/metadata.rb +20 -0
  28. data/lib/moysklad/resources/metadata_indexed.rb +7 -0
  29. data/lib/moysklad/resources/subresource.rb +21 -0
  30. data/lib/moysklad/resources/where_filter.rb +16 -0
  31. data/lib/moysklad/universe.rb +1 -5
  32. data/lib/moysklad/version.rb +1 -1
  33. data/moysklad.gemspec +2 -0
  34. data/scripts/rest.sh +7 -1
  35. data/spec/fixtures/302.raw +15 -0
  36. data/spec/fixtures/400.raw +8 -0
  37. data/spec/fixtures/CustomEntityMetadata_list.raw +14 -0
  38. data/spec/fixtures/CustomEntity_list.raw +14 -0
  39. data/spec/fixtures/Good_e932ebe1-2e22-11e4-9406-002590a28eca.raw +12 -0
  40. data/spec/fixtures/Good_eb77ad57-2e22-11e4-4030-002590a28eca.raw +12 -0
  41. data/spec/fixtures/Goods_list.raw +14 -0
  42. data/spec/fixtures/Metadata_list.raw +14 -0
  43. data/spec/fixtures/attribute_boolean.xml +6 -0
  44. data/spec/fixtures/attribute_dictionary.xml +5 -0
  45. data/spec/fixtures/attribute_double.xml +6 -0
  46. data/spec/fixtures/attribute_file.xml +12 -0
  47. data/spec/fixtures/attribute_long.xml +6 -0
  48. data/spec/fixtures/attribute_text.xml +5 -0
  49. data/spec/fixtures/attribute_time.xml +6 -0
  50. data/spec/fixtures/attribute_url.xml +6 -0
  51. data/spec/fixtures/customer_order.xml +28 -0
  52. data/spec/fixtures/good_with_attributes.raw +12 -0
  53. data/spec/lib/moysklad/entities/attribute_metadata_spec.rb +30 -0
  54. data/spec/lib/moysklad/entities/attribute_spec.rb +36 -0
  55. data/spec/lib/moysklad/entities/custom_entity_metadata_spec.rb +34 -0
  56. data/spec/lib/moysklad/entities/custom_entity_spec.rb +35 -0
  57. data/spec/lib/moysklad/entities/customer_order_position_spec.rb +35 -0
  58. data/spec/lib/moysklad/entities/customer_order_spec.rb +53 -0
  59. data/spec/lib/moysklad/entities/good_spec.rb +46 -0
  60. data/spec/lib/moysklad/resources/base_spec.rb +1 -3
  61. data/spec/lib/moysklad/resources/custom_entity_metadata_spec.rb +13 -0
  62. data/spec/lib/moysklad/resources/good_folders_spec.rb +17 -0
  63. data/spec/lib/moysklad/resources/indexed_spec.rb +31 -3
  64. data/spec/lib/moysklad/resources/metadata_indexed_spec.rb +20 -0
  65. data/spec/lib/moysklad/resources/metadata_spec.rb +15 -0
  66. data/spec/lib/moysklad/resources/subresource_spec.rb +13 -0
  67. data/spec/lib/moysklad/resources_spec.rb +1 -0
  68. data/spec/lib/moysklad/universe_spec.rb +1 -0
  69. data/spec/support/resource.rb +10 -0
  70. metadata +99 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e7ae8b46365bd3f82f6e554164e65f31990c69b
4
- data.tar.gz: b1a26c4014c818b508e4146cfb57ff08affb71d9
3
+ metadata.gz: 4efeba1f53889dcadf798d43f7ead932b79f46aa
4
+ data.tar.gz: 43231bb4ad37775704644f87741327e9fc060758
5
5
  SHA512:
6
- metadata.gz: 4624d904cdbeff5bb751bfc2bdf9cd0a0ba3cb17620602d7cb771a3062c61d840d66c5d938ec1c5cd50b145b597fd76a15743caadc71e19d69d26a80e30aee63
7
- data.tar.gz: 5ccd7a4e1427e12166b2fc4f8f7b7c43856adcaf6b627e5c2637860346872f96f30f95cd52eb95923f2e2084e8963abc5cfc5ca3000e811ca1ffbf8645ce9555
6
+ metadata.gz: 4e4b8adea693b27206bf1bbee368589887e85fff11d0c8c019d8f59606aeaa4ba23fcf8beb8517ec5a3c4e77b9130f9bef29f8687b644f7816892ecaefbb1d4f
7
+ data.tar.gz: c9230163bf46446d6b709b490487048d4e057fcfdf8758b0d15e84d10ccbcb10f1df060b9d9ff0f77169e3b438ce20da4f2d6ec18db90409b00a3b6f003c7845
data/.gitignore CHANGED
@@ -1,5 +1,7 @@
1
1
  *.gem
2
2
  *.rbc
3
+ tags
4
+ gems.tags
3
5
  .bundle
4
6
  .config
5
7
  .yardoc
@@ -1 +1,3 @@
1
1
  language: ruby
2
+ rvm:
3
+ - 2.1.0
data/Guardfile CHANGED
@@ -9,6 +9,11 @@
9
9
  # installed the spring binstubs per the docs)
10
10
  # * zeus: 'zeus rspec' (requires the server to be started separetly)
11
11
  # * 'just' rspec: 'rspec'
12
+ guard 'ctags-bundler', :src_path => ["lib", "spec/support"] do
13
+ watch(/^(app|lib|spec\/support)\/.*\.rb$/)
14
+ watch('Gemfile.lock')
15
+ end
16
+
12
17
  guard :rspec, cmd: 'bundle exec rspec' do
13
18
  watch(%r{^spec/.+_spec\.rb$})
14
19
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
data/Rakefile CHANGED
@@ -6,3 +6,9 @@ begin
6
6
 
7
7
  rescue LoadError
8
8
  end
9
+
10
+ require 'yard'
11
+ YARD::Rake::YardocTask.new do |t|
12
+ t.files = ['lib/**/*.rb'] # optional
13
+ #t.options = ['--any', '--extra', '--opts'] # optional
14
+ end
@@ -40,7 +40,7 @@ class Moysklad::Client
40
40
  def validate res
41
41
  return res.body if res.status == 200
42
42
 
43
- Moysklad::Client::Error.build res
43
+ Moysklad::Client::Errors.build res
44
44
  end
45
45
 
46
46
  end
@@ -1,6 +1,6 @@
1
1
  class Moysklad::Client
2
2
  class Errors
3
- def self.build
3
+ def self.build res
4
4
  Moysklad.logger.warn "Moyskad::Client: #{res.status}: #{res.env.url.to_s}\n#{res.body}"
5
5
 
6
6
  case res.status
@@ -10,8 +10,10 @@ class Moysklad::Client
10
10
  raise UnauthorizedError.new res
11
11
  when 404
12
12
  raise NoResourceFound.new res.body
13
- when 500
13
+ when 500
14
14
  raise ParsedError.new(res)
15
+ when 502
16
+ raise HtmlParsedError.new(res)
15
17
  else
16
18
  raise ParsedError.new(res)
17
19
  end
@@ -36,8 +38,8 @@ class Moysklad::Client
36
38
 
37
39
  class HtmlParsedError < Error
38
40
  def initialize res
39
- @result = res
40
- @message = parse_title res.body
41
+ @result = res
42
+ @message = "[#{res.status}] #{parse_title res.body}"
41
43
  end
42
44
 
43
45
  private
@@ -8,6 +8,7 @@ module Moysklad
8
8
  autoload :Common
9
9
 
10
10
  %w{
11
+ GoodFolder
11
12
  Good
12
13
  Barcode
13
14
  SalePrices
@@ -20,13 +21,17 @@ module Moysklad
20
21
  GoodRef
21
22
  Base
22
23
  CustomerOrder
24
+ CustomEntity
25
+ CustomEntityMetadata
23
26
  Feature
27
+ AttributeMetadata
24
28
  EmbeddedEntityMetadata
25
29
  Price
26
30
  StockTO
27
31
  Company
28
32
  Warehouse
29
33
  Collection
34
+ CustomEntity
30
35
  Page
31
36
  }.each do |m|
32
37
  autoload m
@@ -4,8 +4,33 @@ module Moysklad::Entities
4
4
 
5
5
  tag 'attribute'
6
6
 
7
- attribute :metadataUuid, String
8
- attribute :valueString, String
7
+ attribute :metadataUuid, String
8
+ attribute :valueString, String
9
+ attribute :valueText, String
9
10
 
11
+ attribute :entityValueUuid, String
12
+
13
+ # Объект описывающий тип атритуба
14
+ def metadata universe
15
+ universe.metadata.subresource_by_name(:GoodFolder).find metadataUuid
16
+ end
17
+
18
+ def attributeName universe
19
+ metadata(universe).name
20
+ end
21
+
22
+ def get_value universe
23
+ md = metadata universe
24
+ case md.attrType
25
+ when 'ID_CUSTOM'
26
+ universe.custom_entities.find( entityValueUuid ).name
27
+ when 'TEXT'
28
+ valueText
29
+ when 'STRING'
30
+ valueString
31
+ else
32
+ raise "Не известный тип мета-аттрибута #{md.uuid}: #{md.attrType}"
33
+ end
34
+ end
10
35
  end
11
36
  end
@@ -0,0 +1,27 @@
1
+ module Moysklad::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 dictionatyMetadata universe
19
+ universe.custom_entity_metadata.find dictionaryMetadataUuid
20
+ end
21
+
22
+ def entityMetadata universe
23
+ universe.metadata.find entityMetadataUuid
24
+ end
25
+
26
+ end
27
+ end
@@ -2,5 +2,15 @@ module Moysklad::Entities
2
2
  class Base
3
3
  #include Object
4
4
 
5
+ private
6
+
7
+ def cache ns, key
8
+ @cache||={}
9
+ @cache[ns]||={}
10
+ cc = @cache[ns]
11
+
12
+ cc[key] = yield unless cc.has_key? key
13
+ cc[key]
14
+ end
5
15
  end
6
16
  end
@@ -3,7 +3,6 @@ module Moysklad::Entities::Common
3
3
 
4
4
  included do
5
5
  include HappyMapper
6
- include Moysklad::Entities::XmlFix
7
6
 
8
7
  attribute :readMode, String
9
8
  attribute :changeMode, String
@@ -0,0 +1,18 @@
1
+ # https://online.moysklad.ru/exchange/rest/ms/xml/CustomEntity/list
2
+ # Элемент пользовательского справочника
3
+ # (значения перечисляемых свойств)
4
+ module Moysklad::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,35 @@
1
+ # https://online.moysklad.ru/exchange/rest/ms/xml/CustomEntityMetadata/list
2
+ #
3
+ # Пользовательские справочники
4
+ module Moysklad::Entities
5
+ class CustomEntityMetadata < Base
6
+ include CommonObject
7
+ include XmlFix
8
+
9
+ tag 'customEntityMetadata'
10
+
11
+ attribute :uniqueCode, Boolean
12
+ attribute :codeValueType, Integer
13
+ attribute :independentNameGenerator, Boolean
14
+
15
+ attribute :partialReserve, Boolean
16
+
17
+ attribute :editOnlyByAuthor, Boolean
18
+
19
+ attribute :noEditFromOtherPlaceSource, Boolean
20
+
21
+ attribute :noApplicableFromOtherPlaceSource, Boolean
22
+
23
+ attribute :noEditFromOtherPlaceTarget, Boolean
24
+
25
+ attribute :noApplicableFromOtherPlaceTarget, Boolean
26
+
27
+ # Список перечисляемых значений данного справочника
28
+ #
29
+ # @return [Array[CustomEntity]]
30
+ def entities universe
31
+ universe.custom_entities.where entityMetadataUuid: uuid
32
+ end
33
+
34
+ end
35
+ end
@@ -1,6 +1,10 @@
1
1
  module Moysklad::Entities
2
+ # Пример:
3
+ # https://support.moysklad.ru/hc/ru/articles/203402923-Пример-загрузки-заказа-покупателя-через-REST-API
4
+ #
2
5
  class CustomerOrder < Base
3
6
  include CommonObject
7
+ include XmlFix
4
8
 
5
9
  tag 'customerOrder'
6
10
 
@@ -1,6 +1,7 @@
1
1
  module Moysklad::Entities
2
2
  class CustomerOrderPosition < Base
3
3
  include HappyMapper
4
+ include XmlFix
4
5
 
5
6
  tag 'customerOrderPosition'
6
7
 
@@ -10,6 +10,8 @@ module Moysklad::Entities
10
10
  attribute :independentNameGenerator, Boolean
11
11
  attribute :partialReserve, Boolean
12
12
 
13
+ has_many :attributeMetadata, AttributeMetadata
14
+
13
15
  element :code, String
14
16
  end
15
17
  end
@@ -8,9 +8,8 @@ module Moysklad::Entities
8
8
 
9
9
  attribute :archived, Boolean
10
10
 
11
- has_many :attribute, Moysklad::Entities::Attribute
12
-
13
- has_many :barcode, Moysklad::Entities::Barcode
11
+ has_many :attributes, Moysklad::Entities::Attribute
12
+ has_many :barcodes, Moysklad::Entities::Barcode
14
13
 
15
14
  end
16
15
  end
@@ -1,31 +1,34 @@
1
1
  module Moysklad::Entities
2
2
  class Good < Base
3
3
  include CommonObject
4
+ include Moysklad::Entities::XmlFix
4
5
 
5
6
  tag 'good'
6
7
 
7
8
  attribute :isSerialTrackable, Boolean
8
-
9
9
  attribute :buyPrice, Float
10
10
  attribute :buyCurrencyUuid, String
11
-
12
11
  attribute :minPrice, Float
13
-
14
12
  attribute :salePrice, Float
15
13
  attribute :saleCurrencyUuid, String
16
-
17
14
  attribute :weight, Float
18
15
  attribute :volume, Float
19
-
20
16
  attribute :parentUuid, String
21
-
22
17
  attribute :productCode, String
23
-
24
18
  attribute :uomUuid, String
25
19
 
26
- element :code, String
20
+ element :code, String
21
+ element :salePrices, Moysklad::Entities::SalePrices
22
+
23
+ has_many :attributes, Attribute
27
24
 
28
- element :salePrices, Moysklad::Entities::SalePrices
25
+ # preferences
26
+ # images
29
27
 
28
+ def features universe
29
+ cache :features, universe do
30
+ universe.features.where goodUuid: uuid
31
+ end
32
+ end
30
33
  end
31
34
  end
@@ -0,0 +1,9 @@
1
+ module Moysklad::Entities
2
+ class GoodFolder < Base
3
+ include CommonObject
4
+
5
+ tag 'goodFolder'
6
+
7
+ attribute :productCode, String
8
+ end
9
+ end
@@ -10,6 +10,6 @@ module Moysklad::Entities
10
10
  end
11
11
 
12
12
  attribute :sumInCurrency, Float
13
- attribute :sum, Float
13
+ attribute :sum, Float
14
14
  end
15
15
  end
@@ -1,11 +1,15 @@
1
1
  module Moysklad::Entities::XmlFix
2
2
  extend ::ActiveSupport::Concern
3
3
 
4
- included do
5
-
6
- def to_xml
7
- super(Nokogiri::XML::Builder.new(encoding: 'utf-8')).to_xml
4
+ def to_xml builder = nil,default_namespace = nil,tag_from_parent = nil
5
+ unless builder
6
+ builder = Nokogiri::XML::Builder.new(encoding: 'utf-8')
7
+ write_out_to_xml = true
8
8
  end
9
+
10
+ result = super builder, default_namespace, tag_from_parent
11
+
12
+ write_out_to_xml ? result.to_xml : result
9
13
  end
10
- end
11
14
 
15
+ end
@@ -8,20 +8,16 @@ module Moysklad::Resources
8
8
  self.resources << resource_class
9
9
  end
10
10
 
11
- autoload :Base
12
- autoload :Cached
13
- autoload :Indexed
14
-
11
+ require_relative 'resources/base'
12
+ require_relative 'resources/indexed'
15
13
  require_relative 'resources/stock'
16
-
17
- class Metadata < Base
18
- def self.entity_class
19
- Moysklad::Entities::EmbeddedEntityMetadata
20
- end
21
- end
14
+ require_relative 'resources/metadata'
15
+ require_relative 'resources/custom_entity_metadata'
16
+ require_relative 'resources/metadata_indexed'
17
+ require_relative 'resources/subresource'
22
18
 
23
19
  # Простые ресурсы
24
- %w{Goods Features CustomerOrders Warehouses Attributes Companies Consignments MyCompanies}.each do |klass_name|
20
+ %w{Goods GoodFolders Features CustomEntities CustomerOrders Warehouses Companies Consignments MyCompanies}.each do |klass_name|
25
21
  const_set klass_name, Class.new( Base )
26
22
  end
27
23
 
@@ -6,6 +6,10 @@ class Moysklad::Resources::Base
6
6
  Moysklad::Resources.register_resource superclass
7
7
  end
8
8
 
9
+ def self.indexed *args
10
+ Moysklad::Resources::Indexed.new new(*args)
11
+ end
12
+
9
13
  # https://support.moysklad.ru/hc/ru/articles/203404253-REST-сервис-синхронизации-данных
10
14
  def initialize client: nil
11
15
  raise "Должен быть Moysklad::Client" unless client.is_a? Moysklad::Client
@@ -20,7 +24,7 @@ class Moysklad::Resources::Base
20
24
  parse_collection client.get list_path, params
21
25
  end
22
26
 
23
- def find uuid
27
+ def get uuid
24
28
  parse client.get item_path uuid
25
29
  end
26
30
 
@@ -43,12 +47,17 @@ class Moysklad::Resources::Base
43
47
  def self.entity_class
44
48
  ActiveSupport::Inflector.constantize "Moysklad::Entities::#{type.to_s}"
45
49
  end
50
+
46
51
  private
47
52
 
48
53
  attr_reader :client
49
54
 
50
55
  def prepare_resource resource
51
- resource
56
+ if resource.is_a? Moysklad::Entities::Base
57
+ resource.to_xml.to_s
58
+ else
59
+ resource.to_s
60
+ end
52
61
  end
53
62
 
54
63
  def parse content