moy_sklad 1.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +13 -0
- data/Rakefile +1 -0
- data/bin/gencountry +18 -0
- data/doc/xml/Company.xml +165 -0
- data/doc/xml/CustomEntity.xml +53 -0
- data/doc/xml/CustomerOrder.xml +168 -0
- data/doc/xml/Good.xml +127 -0
- data/doc/xml/GoodFolder.xml +53 -0
- data/doc/xml/MOYsklad.xsd +2450 -0
- data/doc/xml/PaymentIn.xml +81 -0
- data/doc/xml/README.md +1 -0
- data/lib/moy_sklad/client/attribute.rb +119 -0
- data/lib/moy_sklad/client/base.rb +112 -0
- data/lib/moy_sklad/client/collection.rb +52 -0
- data/lib/moy_sklad/client/formatter.rb +37 -0
- data/lib/moy_sklad/client/resource.rb +56 -0
- data/lib/moy_sklad/client.rb +5 -0
- data/lib/moy_sklad/configuration.rb +74 -0
- data/lib/moy_sklad/model/company.rb +23 -0
- data/lib/moy_sklad/model/country.rb +12 -0
- data/lib/moy_sklad/model/custom_entity.rb +4 -0
- data/lib/moy_sklad/model/customer_order.rb +21 -0
- data/lib/moy_sklad/model/data/country_codes.yml +249 -0
- data/lib/moy_sklad/model/demand.rb +20 -0
- data/lib/moy_sklad/model/good.rb +32 -0
- data/lib/moy_sklad/model/good_folder.rb +4 -0
- data/lib/moy_sklad/model/payment_in.rb +9 -0
- data/lib/moy_sklad/model/supply.rb +20 -0
- data/lib/moy_sklad/model/templates/company.builder +132 -0
- data/lib/moy_sklad/model/templates/custom_entity.builder +42 -0
- data/lib/moy_sklad/model/templates/customer_order.builder +151 -0
- data/lib/moy_sklad/model/templates/demand.builder +147 -0
- data/lib/moy_sklad/model/templates/good.builder +83 -0
- data/lib/moy_sklad/model/templates/good_folder.builder +41 -0
- data/lib/moy_sklad/model/templates/payment_in.builder +72 -0
- data/lib/moy_sklad/model/templates/supply.builder +144 -0
- data/lib/moy_sklad/model.rb +13 -0
- data/lib/moy_sklad/nokogiri/document.rb +28 -0
- data/lib/moy_sklad/version.rb +3 -0
- data/lib/moy_sklad.rb +4 -0
- data/moy_sklad.gemspec +28 -0
- data/spec/ms_config.rb +44 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/unit/company_spec.rb +60 -0
- data/spec/unit/country_spec.rb +18 -0
- data/spec/unit/custom_entity_spec.rb +64 -0
- data/spec/unit/customer_order_spec.rb +131 -0
- data/spec/unit/demand_spec.rb +53 -0
- data/spec/unit/fail_spec.rb +12 -0
- data/spec/unit/good_folder_spec.rb +51 -0
- data/spec/unit/good_spec.rb +149 -0
- data/spec/unit/payment_in_spec.rb +120 -0
- data/spec/unit/supply_spec.rb +51 -0
- metadata +211 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<paymentIn readMode="NONE" changeMode="NEIGHBOUR" updated="2013-11-23T15:44:07" updatedBy="string" name="string" stateUuid="string" targetAgentUuid="string" sourceAgentUuid="string" targetStoreUuid="string" sourceStoreUuid="string" applicable="true" projectUuid="string" contractUuid="string" moment="2006-08-19T19:27:14+02:00" targetAccountUuid="string" sourceAccountUuid="string" payerVat="false" retailStoreUuid="string" currencyUuid="string" rate="1.051732E7" vatIncluded="true" created="2017-05-15T08:41:13" createdBy="string" employeeUuid="string" expenseItemUuid="string" incomingDate="2013-12-21T12:32:42+01:00" incomingNumber="string" paymentPurpose="string" vatSum="1.051732E7" commissionReportUuid="string" customerOrderUuid="string" factureOutUuid="string" invoiceOutUuid="string" purchaseReturnUuid="string">
|
3
|
+
<!--Optional:-->
|
4
|
+
<accountUuid>string</accountUuid>
|
5
|
+
<!--Optional:-->
|
6
|
+
<accountId>string</accountId>
|
7
|
+
<!--Optional:-->
|
8
|
+
<uuid>string</uuid>
|
9
|
+
<!--Optional:-->
|
10
|
+
<groupUuid>string</groupUuid>
|
11
|
+
<!--Optional:-->
|
12
|
+
<deleted>2016-01-01T20:07:42</deleted>
|
13
|
+
<!--Optional:-->
|
14
|
+
<code>string</code>
|
15
|
+
<!--Optional:-->
|
16
|
+
<externalcode>string</externalcode>
|
17
|
+
<!--Optional:-->
|
18
|
+
<description>string</description>
|
19
|
+
<!--Zero or more repetitions:-->
|
20
|
+
<attribute readMode="SELF" changeMode="PARENT" updated="2019-08-19T16:35:10" updatedBy="string" metadataUuid="string" valueText="string" valueString="string" doubleValue="1.051732E7" longValue="10" booleanValue="true" timeValue="2013-06-17T19:14:58" entityValueUuid="string" agentValueUuid="string" goodValueUuid="string" placeValueUuid="string" consignmentValueUuid="string" contractValueUuid="string" projectValueUuid="string" employeeValueUuid="string" operationUuid="string">
|
21
|
+
<!--Optional:-->
|
22
|
+
<accountUuid>string</accountUuid>
|
23
|
+
<!--Optional:-->
|
24
|
+
<accountId>string</accountId>
|
25
|
+
<!--Optional:-->
|
26
|
+
<uuid>string</uuid>
|
27
|
+
<!--Optional:-->
|
28
|
+
<groupUuid>string</groupUuid>
|
29
|
+
<!--Optional:-->
|
30
|
+
<deleted>2005-09-12T10:55:02+02:00</deleted>
|
31
|
+
<!--Optional:-->
|
32
|
+
<file readMode="NONE" changeMode="SELF" updated="2015-08-24T01:09:23" updatedBy="string" name="string" created="2015-06-18T00:07:00+02:00" filename="string" miniatureUuid="string">
|
33
|
+
<!--Optional:-->
|
34
|
+
<accountUuid>string</accountUuid>
|
35
|
+
<!--Optional:-->
|
36
|
+
<accountId>string</accountId>
|
37
|
+
<!--Optional:-->
|
38
|
+
<uuid>string</uuid>
|
39
|
+
<!--Optional:-->
|
40
|
+
<groupUuid>string</groupUuid>
|
41
|
+
<!--Optional:-->
|
42
|
+
<deleted>2000-04-21T02:36:55+02:00</deleted>
|
43
|
+
<!--Optional:-->
|
44
|
+
<code>string</code>
|
45
|
+
<!--Optional:-->
|
46
|
+
<externalcode>string</externalcode>
|
47
|
+
<!--Optional:-->
|
48
|
+
<description>string</description>
|
49
|
+
<!--Optional:-->
|
50
|
+
<contents>cXVpc3F1YW0=</contents>
|
51
|
+
</file>
|
52
|
+
</attribute>
|
53
|
+
<!--Zero or more repetitions:-->
|
54
|
+
<document readMode="PARENT" changeMode="PARENT" updated="2008-08-06T16:17:00+02:00" updatedBy="string" name="string" created="2011-12-25T03:49:17" filename="string" miniatureUuid="string" emailedDate="2015-10-10T12:07:56+02:00" publicId="string" operationUuid="string">
|
55
|
+
<!--Optional:-->
|
56
|
+
<accountUuid>string</accountUuid>
|
57
|
+
<!--Optional:-->
|
58
|
+
<accountId>string</accountId>
|
59
|
+
<!--Optional:-->
|
60
|
+
<uuid>string</uuid>
|
61
|
+
<!--Optional:-->
|
62
|
+
<groupUuid>string</groupUuid>
|
63
|
+
<!--Optional:-->
|
64
|
+
<deleted>2018-07-19T10:02:25+02:00</deleted>
|
65
|
+
<!--Optional:-->
|
66
|
+
<code>string</code>
|
67
|
+
<!--Optional:-->
|
68
|
+
<externalcode>string</externalcode>
|
69
|
+
<!--Optional:-->
|
70
|
+
<description>string</description>
|
71
|
+
<!--Optional:-->
|
72
|
+
<contents>YmVsbGE=</contents>
|
73
|
+
</document>
|
74
|
+
<!--Optional:-->
|
75
|
+
<sum sum="1.051732E7" sumInCurrency="1.051732E7"/>
|
76
|
+
<!--Optional:-->
|
77
|
+
<demandsUuid>
|
78
|
+
<!--Zero or more repetitions:-->
|
79
|
+
<demandRef>string</demandRef>
|
80
|
+
</demandsUuid>
|
81
|
+
</paymentIn>
|
data/doc/xml/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Все xml'ки созданы из MOYSklad.xsd при помощи: http://devutilsonline.com/xsd-xml/generate-xml-from-xsd
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Placeholder class used by Nokogiri for create "clean" xml
|
2
|
+
# requests.
|
3
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
4
|
+
|
5
|
+
module MoySklad::Client
|
6
|
+
module Attribute
|
7
|
+
class MissingAttr
|
8
|
+
def method_missing(meth, *args)
|
9
|
+
MissingAttr.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def empty?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Include in baseclass because we need this in ALL subclasses
|
19
|
+
# (also in autocreated by AR)
|
20
|
+
module MissingAttrHandler
|
21
|
+
def method_missing(meth, *args)
|
22
|
+
if meth[-1] != '='
|
23
|
+
begin
|
24
|
+
super
|
25
|
+
rescue
|
26
|
+
MoySklad::Client::Attribute::MissingAttr.new
|
27
|
+
end
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module CustomAttrBehavior
|
35
|
+
|
36
|
+
# Attributes array is widely used in all MS data objects. It handle custom attributes
|
37
|
+
# for each object. For make life easier we're use get/set_attribute functions.
|
38
|
+
|
39
|
+
# Get attrubute from the "attributes" array of the object.
|
40
|
+
#
|
41
|
+
# @attr info [Hash] attribute info hash, should have keys: {:uuid, :value}
|
42
|
+
# @attr value [Object] value to set
|
43
|
+
#
|
44
|
+
def set_attribute(info, value)
|
45
|
+
|
46
|
+
fail ArgumentError, "Argument should be hash with at least [:uuid, :value] keys" unless info.is_a?(Hash)
|
47
|
+
|
48
|
+
info = HashWithIndifferentAccess.new(info)
|
49
|
+
fail ArgumentError, "You must provide keys: [:uuid, :value]" unless info.has_key?(:uuid) || info.has_key?(:value)
|
50
|
+
|
51
|
+
v = find_object(:attribute, :metadataUuid, info[:uuid])
|
52
|
+
if v.nil?
|
53
|
+
data = { metadataUuid: info[:uuid] }
|
54
|
+
data[info[:value]] = value
|
55
|
+
a = create_and_load_resource('Attribute', data)
|
56
|
+
if self.to_a(:attribute).empty?
|
57
|
+
self.attribute = [a]
|
58
|
+
else
|
59
|
+
self.attribute << a
|
60
|
+
end
|
61
|
+
else
|
62
|
+
v.send("#{info[:value]}=".to_sym, value)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
# Set attribute in "attributes" array of the object.
|
68
|
+
#
|
69
|
+
# @attr info [Hash/String] hash with at least [:uuid] key or String with uuid.
|
70
|
+
# if hash containts [:value] key then value will be returned
|
71
|
+
# instead of plceholder object.
|
72
|
+
def get_attribute(info)
|
73
|
+
|
74
|
+
uuid = info if info.is_a?(String) && (info.length == 36)
|
75
|
+
|
76
|
+
if info.is_a?(Hash)
|
77
|
+
info = HashWithIndifferentAccess.new(info)
|
78
|
+
uuid = info[:uuid] if info.is_a?(Hash) && (!info[:uuid].nil? && info[:uuid].length == 36)
|
79
|
+
end
|
80
|
+
|
81
|
+
fail ArgumentError, "Argument should be uuid string or hash with [:uuid] key" if uuid.nil?
|
82
|
+
|
83
|
+
a = find_object(:attribute, :metadataUuid, uuid)
|
84
|
+
|
85
|
+
if info.is_a?(Hash) && info.has_key?(:value)
|
86
|
+
return a.send(info[:value]) if a.respond_to?(info[:value])
|
87
|
+
nil
|
88
|
+
else
|
89
|
+
a
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get object attribute as array.
|
94
|
+
# object.to_a(:some_type) will always return array and of course it can be empty.
|
95
|
+
def to_a(type)
|
96
|
+
|
97
|
+
value = self.send(type)
|
98
|
+
return [] if value.nil? || value.is_a?(MoySklad::Client::Attribute::MissingAttr)
|
99
|
+
|
100
|
+
# Convert
|
101
|
+
self.send("#{type}=", [value]) unless value.is_a?(Array)
|
102
|
+
self.send(type)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Check is nested resource empty or not
|
106
|
+
def empty?
|
107
|
+
attributes.empty?
|
108
|
+
end
|
109
|
+
|
110
|
+
# Remove attribute from object
|
111
|
+
def remove_attr(attribute)
|
112
|
+
attributes.delete(attribute)
|
113
|
+
known_attributes.delete(attribute)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
ActiveResource::Base.send(:include, MissingAttrHandler)
|
118
|
+
ActiveResource::Base.send(:include, CustomAttrBehavior)
|
119
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# ActiveResource base class
|
2
|
+
# All models shoud extend this class
|
3
|
+
|
4
|
+
module MoySklad::Client
|
5
|
+
class Base < ActiveResource::Base
|
6
|
+
self.site = MoySklad.configuration.base_url
|
7
|
+
self.format = Formatter.new
|
8
|
+
self.user = MoySklad.configuration.user_name
|
9
|
+
self.password = MoySklad.configuration.password
|
10
|
+
self.auth_type = :basic
|
11
|
+
|
12
|
+
if ActiveResource::VERSION::STRING >= '4.0.0'
|
13
|
+
self.include_format_in_path = false
|
14
|
+
self.collection_parser = Collection
|
15
|
+
end
|
16
|
+
|
17
|
+
@@template_path = File.join(File.dirname(__FILE__), '..', 'model', 'templates')
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
def find(*args)
|
22
|
+
# Little trick for correct baseclass name
|
23
|
+
self.format.element_name = element_name.classify
|
24
|
+
super(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Custom path builder
|
28
|
+
def element_path(id, prefix_options = {}, query_options = nil)
|
29
|
+
check_prefix_options(prefix_options)
|
30
|
+
|
31
|
+
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
|
32
|
+
"#{prefix(prefix_options)}#{element_name.classify}/" \
|
33
|
+
"#{URI.parser.escape id.to_s}#{query_string(query_options)}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def new_element_path(prefix_options = {})
|
37
|
+
"#{prefix(prefix_options)}#{element_name.classify}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def collection_name
|
41
|
+
@collection_name ||= "#{element_name.classify}/list"
|
42
|
+
end
|
43
|
+
|
44
|
+
if ActiveResource::VERSION::STRING < '4.0.0'
|
45
|
+
def collection_path(prefix_options = {}, query_options = nil)
|
46
|
+
check_prefix_options(prefix_options)
|
47
|
+
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
|
48
|
+
"#{prefix(prefix_options)}#{collection_name}#{query_string(query_options)}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Override create method, this required because moysklad uses PUT instead of POST
|
54
|
+
if ActiveResource::VERSION::STRING < '4.0.0'
|
55
|
+
def create
|
56
|
+
_create
|
57
|
+
end
|
58
|
+
|
59
|
+
def destroy
|
60
|
+
_destroy
|
61
|
+
end
|
62
|
+
else
|
63
|
+
def create
|
64
|
+
run_callbacks :create do _create end
|
65
|
+
end
|
66
|
+
|
67
|
+
def destroy
|
68
|
+
run_callbacks :destroy do _destroy end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def save
|
73
|
+
super
|
74
|
+
self.error.is_a?(MoySklad::Client::Attribute::MissingAttr)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def _create
|
80
|
+
connection.put(new_element_path, encode, self.class.headers).tap do |response|
|
81
|
+
self.id = id_from_response(response)
|
82
|
+
load_attributes_from_response(response)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def _destroy
|
87
|
+
connection.delete(self.class.element_path(uuid), self.class.headers)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Custom data encoder
|
91
|
+
# Template compiled only ONCE !!!
|
92
|
+
def encode
|
93
|
+
compile_template unless respond_to?(:create_xml)
|
94
|
+
create_xml
|
95
|
+
end
|
96
|
+
|
97
|
+
def compile_template
|
98
|
+
file_path = File.join("#{@@template_path}", "#{self.class.element_name}.builder")
|
99
|
+
File.open(file_path) do |f|
|
100
|
+
template = f.read
|
101
|
+
|
102
|
+
self.class.module_eval(<<-CODE)
|
103
|
+
def create_xml
|
104
|
+
builder = ::Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml|
|
105
|
+
#{template}
|
106
|
+
end.to_xml()
|
107
|
+
end
|
108
|
+
CODE
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Resources collection handler
|
2
|
+
|
3
|
+
require 'active_resource'
|
4
|
+
require 'active_support/core_ext/hash/conversions'
|
5
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
6
|
+
|
7
|
+
module MoySklad::Client
|
8
|
+
if ActiveResource::VERSION::STRING < '4.0.0'
|
9
|
+
class Collection
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
delegate :collect, :each, :length, :to => :to_a
|
13
|
+
|
14
|
+
attr_accessor :elements
|
15
|
+
|
16
|
+
def to_a
|
17
|
+
@elements
|
18
|
+
end
|
19
|
+
|
20
|
+
def collect!
|
21
|
+
return @elements unless block_given?
|
22
|
+
set = []
|
23
|
+
each { |o| set << yield(o) }
|
24
|
+
@elements = set
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
alias map! collect!
|
29
|
+
end
|
30
|
+
else
|
31
|
+
class Collection < ActiveResource::Collection
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Collection
|
36
|
+
attr_reader :metadata
|
37
|
+
|
38
|
+
def initialize(data)
|
39
|
+
|
40
|
+
@elements = data[:data]['collection'].delete(data[:object])
|
41
|
+
@elements = [@elements] if @elements.is_a?(Hash)
|
42
|
+
@metadata = HashWithIndifferentAccess.new(data[:data]['collection'])
|
43
|
+
|
44
|
+
@elements ||= []
|
45
|
+
|
46
|
+
# Fix keys
|
47
|
+
[:total, :start, :count].each do |k|
|
48
|
+
@metadata[k] = @metadata[k].to_i if @metadata.has_key?(k)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Custom formatter
|
2
|
+
# Used only on retrive process. Submission encoder live in base.rb
|
3
|
+
|
4
|
+
require 'active_resource'
|
5
|
+
require 'active_support/core_ext/hash/conversions'
|
6
|
+
|
7
|
+
module MoySklad::Client
|
8
|
+
class Formatter
|
9
|
+
include ::ActiveResource::Formats::XmlFormat
|
10
|
+
|
11
|
+
attr_accessor :element_name
|
12
|
+
|
13
|
+
def decode(_data)
|
14
|
+
data = Hash.from_xml(_data)
|
15
|
+
|
16
|
+
if data.has_key?('collection')
|
17
|
+
collection(data)
|
18
|
+
else
|
19
|
+
{data.keys.first.underscore => data.values.first}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def _data(data)
|
24
|
+
{ data: data, object: element_name[0].downcase + element_name[1..-1] }
|
25
|
+
end
|
26
|
+
|
27
|
+
if ActiveResource::VERSION::STRING < '4.0.0'
|
28
|
+
def collection(data)
|
29
|
+
MoySklad::Client::Collection.new(_data(data))
|
30
|
+
end
|
31
|
+
else
|
32
|
+
def collection(data)
|
33
|
+
_data(data)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Nested resources management
|
2
|
+
|
3
|
+
module ActiveResource
|
4
|
+
class Base
|
5
|
+
|
6
|
+
# Nested object finder by type uuid + object uuid.
|
7
|
+
#
|
8
|
+
# MS data model have arrays which contains objects where each object have a special "type"
|
9
|
+
# uuid and object uuid. Type + Object uuids are PK for the object.
|
10
|
+
#
|
11
|
+
# @attr name [Symbol] attribute name
|
12
|
+
# @attr type [String] "type" uuid
|
13
|
+
# @attr key [String] "object" uuid
|
14
|
+
#
|
15
|
+
def find_object(name, type, key)
|
16
|
+
return nil if self.send(name).is_a?(MoySklad::Client::Attribute::MissingAttr)
|
17
|
+
|
18
|
+
create_nested_resource(name)
|
19
|
+
|
20
|
+
# Convert single attr to array
|
21
|
+
self.send("#{name}=", [self.send(name)]) unless self.send(name).is_a?(Array)
|
22
|
+
|
23
|
+
self.send(name).each do |v|
|
24
|
+
return v if v.send(type) == key
|
25
|
+
end
|
26
|
+
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Construct nested resource class and load with given attributes
|
33
|
+
# NB: ALL nested classes should be created through this way.
|
34
|
+
def create_and_load_resource(name, attributes = nil)
|
35
|
+
res = find_or_create_resource_for(name).new
|
36
|
+
res.load(attributes) if !attributes.nil?
|
37
|
+
res
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_nested_collection(name)
|
41
|
+
create_nested_collection_or_resource(name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_nested_resource(name)
|
45
|
+
create_nested_collection_or_resource(name, false)
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_nested_collection_or_resource(name, collection = true)
|
49
|
+
name = name.to_s
|
50
|
+
if !known_attributes.include?(name) || attributes[name].nil?
|
51
|
+
known_attributes << name
|
52
|
+
attributes[name] = collection ? [] : create_and_load_resource(name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module MoySklad
|
2
|
+
# Returns the global [Configuration](MoySklad/Configuration) object. While you
|
3
|
+
# _can_ use this method to access the configuration, the more common
|
4
|
+
# convention is to use [MoySklad.configure](MoySklad#configure-class_method).
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# MoySklad.configuration.user_name = 'admin@example'
|
8
|
+
# @see MoySklad.configure
|
9
|
+
# @see Configuration
|
10
|
+
def self.configuration
|
11
|
+
@configuration ||= MoySklad::Configuration.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# Yields the global configuration to a block.
|
15
|
+
# @yield [Configuration] global configuration
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# MoySklad.configure do |config|
|
19
|
+
# config.user_name 'admin@example'
|
20
|
+
# config.password '1234567890'
|
21
|
+
# end
|
22
|
+
# @see Configuration
|
23
|
+
def self.configure
|
24
|
+
yield configuration if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
# Stores runtime configuration information.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# MoySklad.configure do |config|
|
31
|
+
# config.user_name 'admin@example'
|
32
|
+
# config.password '1234567890'
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# @see MoySklad.configure
|
36
|
+
class Configuration
|
37
|
+
# User name for authentication.
|
38
|
+
# @attr value [String] defaults to `''`
|
39
|
+
attr_reader :user_name
|
40
|
+
|
41
|
+
def user_name=(v)
|
42
|
+
MoySklad::Client::Base.user = @user_name = v
|
43
|
+
end
|
44
|
+
|
45
|
+
# Password for authentication.
|
46
|
+
# @attr value [String] defaults to `''`
|
47
|
+
attr_reader :password
|
48
|
+
|
49
|
+
def password=(v)
|
50
|
+
MoySklad::Client::Base.password = @password = v
|
51
|
+
end
|
52
|
+
|
53
|
+
# Base url.
|
54
|
+
# @attr value [String] defaults to
|
55
|
+
# `'https://online.moysklad.ru/exchange/rest/ms/xml'`
|
56
|
+
attr_reader :base_url
|
57
|
+
|
58
|
+
def base_url=(v)
|
59
|
+
MoySklad::Client::Base.site = @base_url = v
|
60
|
+
end
|
61
|
+
|
62
|
+
# Currency UUID.
|
63
|
+
# @attr value [String] defaults to
|
64
|
+
# `'131bf5ff-1ee5-11e4-67ed-002590a28eca'`
|
65
|
+
attr_accessor :currency
|
66
|
+
|
67
|
+
def initialize
|
68
|
+
@user_name = ''
|
69
|
+
@password = ''
|
70
|
+
@base_url = 'https://online.moysklad.ru/exchange/rest/ms/xml'
|
71
|
+
@currency = '131bf5ff-1ee5-11e4-67ed-002590a28eca'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module MoySklad::Model
|
2
|
+
class Company < MoySklad::Client::Base
|
3
|
+
def initialize(*args)
|
4
|
+
super(*args)
|
5
|
+
|
6
|
+
create_nested_resource(:contact)
|
7
|
+
create_nested_resource(:requisite)
|
8
|
+
create_nested_resource(:tags)
|
9
|
+
create_nested_collection(:contactPerson)
|
10
|
+
requisite.create_nested_resource(:bankAccount)
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_contact(options)
|
14
|
+
|
15
|
+
# We're always have one person
|
16
|
+
if to_a(:contactPerson).empty?
|
17
|
+
contactPerson << create_and_load_resource('contactPerson', options)
|
18
|
+
else
|
19
|
+
to_a(:contactPerson)[0].load(options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module MoySklad::Model
|
4
|
+
class Country < MoySklad::Client::Base
|
5
|
+
class << self
|
6
|
+
def uuid_from_code(code)
|
7
|
+
@_country_cache ||= YAML.load_file(File.join(File.dirname(__FILE__), 'data', 'country_codes.yml'))
|
8
|
+
@_country_cache[code.to_s]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MoySklad::Model
|
2
|
+
class CustomerOrder < MoySklad::Client::Base
|
3
|
+
|
4
|
+
def initialize(*args)
|
5
|
+
super(*args)
|
6
|
+
create_nested_collection(:customerOrderPosition)
|
7
|
+
create_nested_collection(:attribute)
|
8
|
+
create_nested_resource(:sum)
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_item(id, options = {})
|
12
|
+
item = create_and_load_resource("CustomerOrderPosition",
|
13
|
+
{ goodUuid: id }.merge!(options))
|
14
|
+
if to_a(:customerOrderPosition).empty?
|
15
|
+
self.customerOrderPosition = [item]
|
16
|
+
else
|
17
|
+
self.customerOrderPosition << item
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|