rs.ge 0.1.0.beta2 → 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,6 +7,12 @@ class RS::BaseRequest
7
7
  # Waybill service WSDL location.
8
8
  WAYBILL_SERVICE_URL = 'http://services.rs.ge/WayBillService/WayBillService.asmx?WSDL'
9
9
 
10
+ # Defaults
11
+ DEFAULTS = {su: 'dimitri1979', sp: '123456'}
12
+
13
+ # Last error code.
14
+ attr_accessor :last_error_code
15
+
10
16
  # Getting Savon client.
11
17
  def waybill_client
12
18
  Savon::Client.new { wsdl.document = WAYBILL_SERVICE_URL }
@@ -14,6 +20,13 @@ class RS::BaseRequest
14
20
 
15
21
  # Validates presence of specified keys in the #{params} hash.
16
22
  def validate_presence_of(params, *keys)
23
+ # XXX: do we always need this replacement???
24
+ [:su, :sp].each do |sym|
25
+ if keys.include?(sym) and params[sym].blank?
26
+ params[sym] = RS.config.send(sym)
27
+ end
28
+ end
29
+ # <-- XXX
17
30
  diff = keys - params.keys
18
31
  raise ArgumentError, "The following parameter(s) not specified: #{diff.to_s[1..-2]}" unless diff.empty?
19
32
  end
@@ -0,0 +1,19 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'singleton'
3
+
4
+ module RS
5
+
6
+ # RS configuration.
7
+ class Config
8
+ include Singleton
9
+
10
+ attr_accessor :sp, :su, :validate_remote
11
+ end
12
+
13
+ class << self
14
+ def config
15
+ RS::Config.instance
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,111 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'singleton'
3
+
4
+ module RS
5
+ # Unit, which cannot be found in main list.
6
+ UNIT_OTHERS = 99
7
+
8
+ WAYBILL_TYPE_INNER = 1
9
+ WAYBILL_TYPE_TRANS = 2
10
+ WAYBILL_TYPE_WITHOUT_TRANS = 3
11
+ WAYBILL_TYPE_DISTR = 4
12
+ WAYBILL_TYPE_RETRN = 5
13
+ WAYBILL_TYPE_SUBWB = 6
14
+
15
+ WAYBILL_TYPES = {
16
+ WAYBILL_TYPE_INNER => 'შიდა გადაზიდვა',
17
+ WAYBILL_TYPE_TRANS => 'ტრანსპორტირებით',
18
+ WAYBILL_TYPE_WITHOUT_TRANS => 'ტრანსპორტირების გარეშე',
19
+ WAYBILL_TYPE_DISTR => 'დისტრიბუცია',
20
+ WAYBILL_TYPE_RETRN => 'უკან დაბრუნება',
21
+ WAYBILL_TYPE_SUBWB => 'ქვე-ზედნადები'
22
+ }
23
+
24
+ TRANS_VEHICLE = 1
25
+ TRANS_RAILWAY = 2
26
+ TRANS_AIR = 3
27
+ TRANS_OTHER = 4
28
+ TRANS_VEHICLE_FRGN = 6
29
+
30
+ TRANSPORT_TYPES = {
31
+ TRANS_VEHICLE => 'საავტომობილო',
32
+ TRANS_RAILWAY => 'სარკინიგზო',
33
+ TRANS_AIR => 'საავიაციო',
34
+ TRANS_OTHER => 'სხვა',
35
+ TRANS_VEHICLE_FRGN => 'საავტომობილო - უცხო ქვეყნის'
36
+ }
37
+
38
+ class DictionaryRequest < BaseRequest
39
+
40
+ include Singleton
41
+
42
+ # Returns RS.GE units.
43
+ def units(opts = {})
44
+ validate_presence_of(opts, :su, :sp)
45
+ response = waybill_client.request 'get_waybill_units' do
46
+ soap.body = { 'su' => opts[:su], 'sp' => opts[:sp] }
47
+ end
48
+ resp = response.to_hash[:get_waybill_units_response][:get_waybill_units_result][:waybill_units][:waybill_unit]
49
+ units = {}
50
+ resp.each do |unit|
51
+ units[unit[:id].to_i] = unit[:name]
52
+ end
53
+ units
54
+ end
55
+
56
+ # Returns RS.GE waybill types.
57
+ def waybill_types(opts = {})
58
+ validate_presence_of(opts, :su, :sp)
59
+ response = waybill_client.request 'get_waybill_types' do
60
+ soap.body = { 'su' => opts[:su], 'sp' => opts[:sp] }
61
+ end
62
+ resp = response.to_hash[:get_waybill_types_response][:get_waybill_types_result][:waybill_types][:waybill_type]
63
+ types = {}
64
+ resp.each do |type|
65
+ types[type[:id].to_i] = type[:name]
66
+ end
67
+ types
68
+ end
69
+
70
+ # Returns RS.GE transport types.
71
+ def transport_types(opts = {})
72
+ validate_presence_of(opts, :su, :sp)
73
+ response = waybill_client.request 'get_trans_types' do
74
+ soap.body = { 'su' => opts[:su], 'sp' => opts[:sp] }
75
+ end
76
+ resp = response.to_hash[:get_trans_types_response][:get_trans_types_result][:transport_types][:transport_type]
77
+ types = {}
78
+ resp.each do |type|
79
+ types[type[:id].to_i] = type[:name]
80
+ end
81
+ types
82
+ end
83
+
84
+ # Returns name by given TIN number.
85
+ def get_name_from_tin(params = {})
86
+ validate_presence_of(params, :su, :sp, :tin)
87
+ response = waybill_client.request 'get_name_from_tin' do
88
+ soap.body = params
89
+ end
90
+ response.to_hash[:get_name_from_tin_response][:get_name_from_tin_result]
91
+ end
92
+
93
+ # Checks whether given argument is a correct personal TIN.
94
+ def personal_tin?(tin)
95
+ tin =~ /^[0-9]{11}$/
96
+ end
97
+
98
+ # Checks whether given argument is a correct corporate TIN.
99
+ def corporate_tin?(tin)
100
+ tin =~ /^[0-9]{9}$/
101
+ end
102
+
103
+ end
104
+
105
+ class << self
106
+ def dict
107
+ RS::DictionaryRequest.instance
108
+ end
109
+ end
110
+
111
+ end
@@ -0,0 +1,92 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'singleton'
3
+
4
+ module RS
5
+ # System administration related methods.
6
+ class SysRequest < BaseRequest
7
+ include Singleton
8
+
9
+ # Get your outside IP address.
10
+ def what_is_my_ip
11
+ response = waybill_client.request 'what_is_my_ip'
12
+ response.to_hash[:what_is_my_ip_response][:what_is_my_ip_result].strip
13
+ end
14
+
15
+ # Create service user.
16
+ #
17
+ # * `username` -- login for the main user
18
+ # * `password` -- password for the main user
19
+ # * `ip` -- your IP address
20
+ # * `name` -- some name for this user/ip configuration
21
+ # * `su` -- new user login
22
+ # * `sp` -- new user password
23
+ def create_user(opts)
24
+ validate_presence_of(opts, :username, :password, :ip, :name, :su, :sp)
25
+ response = waybill_client.request 'create_service_user' do
26
+ soap.body = {'user_name' => opts[:username], 'user_password' => opts[:password], 'ip' => opts[:ip], 'name' => opts[:name], 'su' => opts[:su], 'sp' => opts[:sp]}
27
+ end
28
+ response.to_hash[:create_service_user_response][:create_service_user_result]
29
+ end
30
+
31
+ # Update service user.
32
+ #
33
+ # * `username` -- login for the main user
34
+ # * `password` -- password for the main user
35
+ # * `ip` -- your IP address
36
+ # * `name` -- some name for this user/ip configuration
37
+ # * `su` -- user login
38
+ # * `sp` -- user's passwrod
39
+ def update_user(opts)
40
+ validate_presence_of(opts, :username, :password, :ip, :name, :su, :sp)
41
+ response = waybill_client.request 'update_service_user' do
42
+ soap.body = {'user_name' => opts[:username], 'user_password' => opts[:password], 'ip' => opts[:ip], 'name' => opts[:name], 'su' => opts[:su], 'sp' => opts[:sp]}
43
+ end
44
+ response.to_hash[:update_service_user_response][:update_service_user_result]
45
+ end
46
+
47
+ # Check service user. Also used for getting user's ID and payer's ID.
48
+ #
49
+ # possible parameters:
50
+ #
51
+ # `su` -- service username
52
+ # `sp` -- service password
53
+ #
54
+ # Returns hash with the following structure:
55
+ #
56
+ # ```
57
+ # {payer: 'payer unique ID', user: 'user unique ID'}
58
+ # ```
59
+ def check_user(opts)
60
+ validate_presence_of(opts, :su, :sp)
61
+ response = waybill_client.request 'chek_service_user' do
62
+ soap.body = {'su' => opts[:su], 'sp' => opts[:sp] }
63
+ end
64
+ if response[:chek_service_user_response][:chek_service_user_result]
65
+ payer_id = response[:chek_service_user_response][:un_id]
66
+ user_id = response[:chek_service_user_response][:s_user_id]
67
+ {payer: payer_id, user: user_id}
68
+ end
69
+ end
70
+
71
+ # Returns error codes.
72
+ def error_codes(opts = {})
73
+ validate_presence_of(opts, :su, :sp)
74
+ response = waybill_client.request 'get_error_codes' do
75
+ soap.body = {'su' => opts[:su], 'sp' => opts[:sp] }
76
+ end
77
+ errors = {}
78
+ response[:get_error_codes_response][:get_error_codes_result][:error_codes][:error_code].each do |el|
79
+ errors[el[:id].to_i] = el[:text]
80
+ end
81
+ errors
82
+ end
83
+
84
+ end
85
+
86
+ class << self
87
+ def sys
88
+ RS::SysRequest.instance
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,123 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'singleton'
3
+
4
+ module RS
5
+
6
+ class WaybillRequest < BaseRequest
7
+ include Singleton
8
+
9
+ # Save given waybill.
10
+ def save_waybill(waybill, opts = {})
11
+ validate_presence_of(opts, :su, :sp)
12
+ response = waybill_client.request 'save_waybill' do |soap|
13
+ soap.body do |xml|
14
+ xml.ins0 :su, opts[:su]
15
+ xml.ins0 :sp, opts[:sp]
16
+ xml.ins0 :waybill do |b|
17
+ waybill.to_xml b
18
+ end
19
+ end
20
+ end
21
+ hash_results = response.to_hash[:save_waybill_response][:save_waybill_result][:result]
22
+ if hash_results[:status].to_i == 0
23
+ waybill.id = hash_results[:id].to_i == 0 ? nil : hash_results[:id].to_i
24
+ waybill.error_code = 0
25
+ items_hash = hash_results[:goods_list][:goods]
26
+ items_hash = [items_hash] if items_hash.instance_of? Hash
27
+ (0..items_hash.size-1).each do |i|
28
+ waybill.items[i].id = items_hash[i][:id].to_i
29
+ #waybill.items[i].error_code = items_hash[i][:error].to_i
30
+ end
31
+ else
32
+ waybill.error_code = hash_results[:status].to_i
33
+ end
34
+ end
35
+
36
+ # Get saved waybill.
37
+ def get_waybill(opts)
38
+ validate_presence_of(opts, :id, :su, :sp)
39
+ response = waybill_client.request 'get_waybill' do
40
+ soap.body = {'su' => opts[:su], 'sp' => opts[:sp], 'waybill_id' => opts[:id]}
41
+ end
42
+ wb = RS::Waybill.new
43
+ #puts response.to_hash
44
+ wb.init_from_hash(response.to_hash[:get_waybill_response][:get_waybill_result][:waybill])
45
+ end
46
+
47
+ # Activate waybill.
48
+ def activate_waybill(opts)
49
+ validate_presence_of(opts, :id, :su, :sp)
50
+ if opts[:date]
51
+ response = waybill_client.request 'send_waybil_vd' do
52
+ soap.body = { 'su' => opts[:su], 'sp' => opts[:sp], 'begin_date' => opts[:date].strftime('%Y-%m-%dT%H:%M:%S'), 'waybill_id' => opts[:id] }
53
+ end
54
+ response.to_hash[:send_waybil_vd_response][:send_waybil_vd_result]
55
+ else
56
+ response = waybill_client.request 'send_waybill' do
57
+ soap.body = { 'su' => opts[:su], 'sp' => opts[:sp], 'waybill_id' => opts[:id] }
58
+ end
59
+ response.to_hash[:send_waybill_response][:send_waybill_result]
60
+ end
61
+ end
62
+
63
+ # Close waybill.
64
+ def close_waybill(opts)
65
+ validate_presence_of(opts, :su, :sp, :id)
66
+ if opts[:date]
67
+ response = waybill_client.request 'close_waybill_vd' do
68
+ soap.body = { 'su' => opts[:su], 'sp' => opts[:sp], 'delivery_date' => opts[:date].strftime('%Y-%m-%dT%H:%M:%S'), 'waybill_id' => opts[:id] }
69
+ end
70
+ response.to_hash[:close_waybill_vd_response][:close_waybill_vd_result].to_i == 1
71
+ else
72
+ response = waybill_client.request 'close_waybill' do
73
+ soap.body = { 'su' => opts[:su], 'sp' => opts[:sp], 'waybill_id' => opts[:id] }
74
+ end
75
+ response.to_hash[:close_waybill_response][:close_waybill_result].to_i == 1
76
+ end
77
+ end
78
+
79
+ # Delete waybill.
80
+ # This operation is permitted only for waybill with RS::Waybill::STATUS_SAVED status.
81
+ def delete_waybill(opts)
82
+ validate_presence_of(opts, :id, :su, :sp)
83
+ response = waybill_client.request 'del_waybill' do |soap|
84
+ soap.body = {'su' => opts[:su], 'sp' => opts[:sp], 'waybill_id' => opts[:id]}
85
+ end
86
+ response.to_hash[:del_waybill_response][:del_waybill_result].to_i == 1
87
+ end
88
+
89
+ # Deactivate waybill.
90
+ # This operation is permitted only for waybill with RS::Waybill::STATUS_ACTIVE or RS::Waybill::STATUS_CLOSED statuses.
91
+ def deactivate_waybill(opts)
92
+ validate_presence_of(opts, :id, :su, :sp)
93
+ response = waybill_client.request 'ref_waybill' do |soap|
94
+ soap.body = {'su' => opts[:su], 'sp' => opts[:sp], 'waybill_id' => opts[:id]}
95
+ end
96
+ response.to_hash[:ref_waybill_response][:ref_waybill_result].to_i == 1
97
+ end
98
+
99
+ # Save this waybill as invoice, related to this waybill.
100
+ # Returns invoice ID (or `nil` if the save operation was unsuccessfull).
101
+ def save_invoice(opts)
102
+ validate_presence_of(opts, :id, :su, :sp)
103
+ response = waybill_client.request 'save_invoice' do |soap|
104
+ soap.body = {'su' => opts[:su], 'sp' => opts[:sp], 'waybill_id' => opts[:id], 'in_inv_id' => (opts[:invoice_id] || 0)}
105
+ end
106
+ resp = response.to_hash[:save_invoice_response][:save_invoice_result].to_i
107
+ if resp == 1
108
+ response.to_hash[:save_invoice_response][:out_inv_id].to_i
109
+ else
110
+ self.last_error_code = resp
111
+ nil
112
+ end
113
+ end
114
+
115
+ end
116
+
117
+ class << self
118
+ def wb
119
+ RS::WaybillRequest.instance
120
+ end
121
+ end
122
+
123
+ end
data/lib/rs/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module RS
3
- VERSION = '0.1.0.beta2'
3
+ VERSION = '0.1.0.rc1'
4
4
  end
data/rs.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_development_dependency 'rspec', '~> 2'
22
- s.add_runtime_dependency 'savon'
22
+ s.add_runtime_dependency 'savon', '0.9.9'
23
23
  s.add_runtime_dependency 'httpi'
24
24
  s.add_runtime_dependency 'prawn', '~>0.12'
25
25
  s.add_runtime_dependency 'c12-commons', '~> 0.0.5'
data/spec/helpers.rb ADDED
@@ -0,0 +1,41 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ ORG_01 = {id: 731937, tin: '206322102', name: 'სატესტო კოდი'}
4
+ ORG_02 = {id: -1, tin: '12345678910', name: 'სატესტო სატესტო'}
5
+ USER01 = {id: 46362, username: 'tbilisi', password: '123456', payer: ORG_01[:id], payer_tin: ORG_01[:tin], payer_name: ORG_01[:name]}
6
+
7
+ def create_waybill(opts = {})
8
+ RS::Waybill.new(id: opts[:id] || 0,
9
+ type: opts[:type] || RS::WAYBILL_TYPE_TRANS,
10
+ status: opts[:status] || RS::Waybill::STATUS_SAVED,
11
+ seller_id: USER01[:payer], seller_tin: USER01[:payer_tin], seller_name: USER01[:payer_name],
12
+ buyer_tin: opts[:buyer_tin] || ORG_02[:tin],
13
+ buyer_name: opts[:buyer_name] || ORG_02[:name],
14
+ check_buyer_tin: true,
15
+ seller_info: opts[:seller_info], buyer_info: opts[:buyer_info],
16
+ driver_tin: opts[:dirver_tin] || '02001000490',
17
+ driver_name: opts[:dirver_name] || 'დიმიტრი ყურაშვილი',
18
+ check_driver_tin: true,
19
+ start_address: opts[:start_address] || 'ქ. აბაშა, კაჭარავას 35',
20
+ end_address: opts[:end_address] || 'ქ. სენაკი, თავისუფლების 10',
21
+ transportation_cost: opts[:transportation_cost] || 0,
22
+ transportation_cost_payer: opts[:transportation_cost_payer] || 1,
23
+ transport_type_id: opts[:transport_type_id] || RS::TRANS_VEHICLE,
24
+ car_number: opts[:car_number] || 'wdw842',
25
+ comment: opts[:comment], user_id: USER01[:id],
26
+ items: opts[:items]
27
+ )
28
+ end
29
+
30
+ def create_item(opts = {})
31
+ RS::WaybillItem.new(id: opts[:id] || 0,
32
+ bar_code: opts[:bar_code] || '001',
33
+ prod_name: opts[:prod_name] || 'Tomato',
34
+ unit_id: opts[:unit_id] || RS::UNIT_OTHERS,
35
+ unit_name: opts[:unit_name] || 'kg',
36
+ quantity: opts[:quantity] || 1,
37
+ price: opts[:price] || 1,
38
+ vat_type: opts[:vat_type] || RS::VAT_COMMON,
39
+ delete: false
40
+ )
41
+ end
@@ -0,0 +1,99 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ RSpec::Matchers.define :have_error_field do |fld|
5
+ match { |obj| !obj.errors[fld].blank? }
6
+ end
7
+
8
+ describe 'WaybillItem validation' do
9
+ before(:all) do
10
+ @item = RS::WaybillItem.new
11
+ @item.validate
12
+ end
13
+ subject { @item }
14
+ it { should have_error_field :bar_code }
15
+ it { should have_error_field :prod_name }
16
+ it { should have_error_field :unit_id }
17
+ it { should_not have_error_field :unit_name }
18
+ it { should have_error_field :quantity }
19
+ it { should have_error_field :price }
20
+ context 'define bar-code' do
21
+ before(:all) do
22
+ @item.bar_code = '001'
23
+ @item.validate
24
+ end
25
+ subject { @item }
26
+ it { should_not have_error_field :bar_code }
27
+ end
28
+ context 'define production-name' do
29
+ before(:all) do
30
+ @item.prod_name = 'tomato'
31
+ @item.validate
32
+ end
33
+ subject { @item }
34
+ it { should_not have_error_field :prod_name }
35
+ end
36
+ context 'define unit = 99' do
37
+ before(:all) do
38
+ @item.unit_id = RS::UNIT_OTHERS
39
+ @item.validate
40
+ end
41
+ subject { @item }
42
+ it { should_not have_error_field :unit_id }
43
+ it { should have_error_field :unit_name }
44
+ context('add unit-name') do
45
+ before(:all) do
46
+ @item.unit_name = 'kg'
47
+ @item.validate
48
+ end
49
+ subject { @item }
50
+ it { should_not have_error_field :unit_id }
51
+ it { should_not have_error_field :unit_name }
52
+ end
53
+ end
54
+ context 'define q < 0' do
55
+ before(:all) do
56
+ @item.quantity = -100
57
+ @item.validate
58
+ end
59
+ subject { @item }
60
+ it { should have_error_field :quantity }
61
+ end
62
+ context 'define q > 0' do
63
+ before(:all) do
64
+ @item.quantity = +100
65
+ @item.validate
66
+ end
67
+ subject { @item }
68
+ it { should_not have_error_field :quantity }
69
+ end
70
+ context 'define p < 0' do
71
+ before(:all) do
72
+ @item.price = -10
73
+ @item.validate
74
+ end
75
+ subject { @item }
76
+ it { should have_error_field :price }
77
+ end
78
+ context 'define p >0' do
79
+ before(:all) do
80
+ @item.price = +10
81
+ @item.validate
82
+ end
83
+ subject { @item }
84
+ it { should_not have_error_field :price }
85
+ end
86
+ end
87
+
88
+ describe 'Waybill validation' do
89
+ before(:all) do
90
+ @waybill = RS::Waybill.new
91
+ @waybill.validate
92
+ end
93
+ subject { @waybill }
94
+ it { should have_error_field :buyer_tin }
95
+ it { should_not have_error_field :buyer_name }
96
+ it { should have_error_field :start_address }
97
+ it { should have_error_field :end_address }
98
+
99
+ end