rs.ge 0.1.0.beta2 → 0.1.0.rc1

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.
@@ -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