moy_sklad 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|