musoni_ruby 0.0.01

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.
@@ -0,0 +1,77 @@
1
+ module Musoni
2
+ class SavingsAccount < Musoni::Endpoint
3
+ attr_writer :transactions, :payable_items
4
+
5
+ class << self
6
+
7
+ # Musoni::SavingsAccount.all()
8
+ def all(offset:1,limit:100)
9
+ url = "/savingsaccounts"
10
+ Musoni::Fetch.get(url,query:{offset:offset,limit:limit}).pageItems
11
+ end
12
+
13
+ # Musoni::SavingsAccount.find(savingsaccount_id)
14
+ def find(savingsaccount_id,fetch:true)
15
+ url = "/savingsaccounts/#{savingsaccount_id}?associations=all"
16
+ response = Musoni::Fetch.get(url) if fetch
17
+ savingsaccount = new(id:savingsaccount_id,response:response)
18
+ end
19
+
20
+ # account_attributes = {:clientId=>"1",:productId=>"1",:submittedOnDate=>"13-05-2015",:fieldOfficerId=>"1",:charges=>[],:allowOverdraft=>false}
21
+ # Musoni::SavingsAccount.create(account_attributes)
22
+ def create(options={})
23
+ url = "/savingsaccounts"
24
+ response = Musoni::Fetch.post(url,options)
25
+ new(options.merge!(id:response.savingsId ,response:response)) rescue response
26
+ end
27
+
28
+ end
29
+
30
+ # # date = {:approvedOnDate=>"13-05-2015"}
31
+ # # account.activate(date)
32
+ %w{approve activate}.each do |m|
33
+ define_method m do |options={}|
34
+ options[:"#{m}dOnDate"] ||= Time.now.strftime("%d-%m-%Y")
35
+ url = "/savingsaccounts/#{self.id}?command=#{m}"
36
+ response = Musoni::Fetch.post(url,options)
37
+ new(options.merge!(id:response.savingsId ,response:response)) rescue response
38
+ end
39
+ end
40
+
41
+ # transaction = {:transactionDate=>"15-05-2015",:transactionAmount=>"100",:receiptNumber=>"ABC",:paymentTypeId=>"177"}
42
+ # # account.activate(date)
43
+ %w{deposit withdrawal}.each do |m|
44
+ define_method m do |options={}|
45
+ options[:transactionDate] ||= Time.now.strftime("%d-%m-%Y")
46
+ url = "/savingsaccounts/#{self.id}/transactions?command=#{m}"
47
+ response = Musoni::Fetch.post(url,options)
48
+ new(options.merge!(id:response.savingsId ,response:response)) rescue response
49
+ end
50
+ end
51
+
52
+ # # savingsaccount.update(name:new_name)
53
+ # def update(options)
54
+ # url = "/savingsaccounts/#{self.id}"
55
+ # response = Musoni::Fetch.put(url,options)
56
+ # self.response = response
57
+ # end
58
+
59
+
60
+ # # Musoni::SavingsAccount.find(26, fetch:false).transactions(offset:1,limit:100)
61
+ # def transactions(offset:1,limit:100)
62
+ # find_all(offset:offset,limit:limit)
63
+ # end
64
+
65
+ # # Musoni::SavingsAccount.find(26, fetch:false).payable_items(offset:1,limit:100)
66
+ # def payable_items(offset:1,limit:100)
67
+ # find_all(offset:offset,limit:limit)
68
+ # end
69
+
70
+ protected
71
+
72
+ def after_initialize
73
+ @endpoint = 'savingsaccounts'
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,53 @@
1
+ module Musoni
2
+ class Fetch
3
+ include HTTParty
4
+
5
+ base_uri "https://demo.musonisystem.com:8443/api/v1"
6
+ parser proc {|data| Hashie::Mash.new(response: (JSON.parse(data) rescue {data:data}.to_json) ).response}
7
+ format :json
8
+ headers
9
+
10
+ class << self
11
+ def headers
12
+ Musoni.configuration.header.merge!(super)
13
+ end
14
+
15
+ %w(get put post delete).each do |m|
16
+ define_method m do |path, options={}, &block|
17
+ # body = date_parameters(options).merge!(options)
18
+ options = {body: date_parameters(options).merge!(options).to_json}
19
+
20
+ res = perform_request Net::HTTP::Put, path, options, &block if m == 'put'
21
+ res = perform_request Net::HTTP::Get, path, options, &block if m == 'get'
22
+ res = perform_request Net::HTTP::Post, path, options, &block if m == 'post'
23
+ res = perform_request Net::HTTP::Delete, path, options, &block if m == 'delete'
24
+ save_json(res) if load_json?
25
+ res
26
+ end
27
+ end
28
+
29
+ def save_json(response)
30
+ request_method = response.request.http_method.name.split('::').last.upcase
31
+ file_path = response.request.path.to_s
32
+ slash,model,*file_name = file_path.split('?')[0].split(/\/|\?/)
33
+ file_location = "lib/musoni_ruby/support/fake_musoni/#{model}/#{request_method}_#{file_name.join('_')}.json"
34
+ File.write(file_location, response.body)
35
+ end
36
+
37
+ def load_json?
38
+ # load JSON if WebMock is off while testing and only in local env with load musoni turned on
39
+ defined?(WebMock).nil? and ENV['CI_TEST'].nil? and defined?(Minitest) and ENV['LOAD_MUSONI'] == "true"
40
+ end
41
+
42
+ def date_parameters(options)
43
+ # bp
44
+ if options.map{|k,v| k.to_s }.grep(/Date/).any?
45
+ {dateFormat:"dd-MM-yyyy", locale:"en_GB"}
46
+ else
47
+ {}
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+ end
File without changes
File without changes
@@ -0,0 +1,25 @@
1
+ require 'sinatra/base'
2
+ require 'tilt/erb'
3
+
4
+ class FakeMusoni < Sinatra::Base
5
+
6
+ [ :get, :post, :put, :delete ].each do |method|
7
+ send method, /.*/ do
8
+ # if (request.env['HTTP_X_WSSE'].empty? rescue true)
9
+ # [200, {}, [{base:["Authentication Failed"]}.to_json]]
10
+ # else
11
+ slash,api,v,model,*path = request.path_info.split('?')[0].split(/\/|\?/)
12
+ json_response 200, "#{model}/#{request.request_method}_#{path.join('_')}.json"
13
+ # end
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def json_response(response_code, file_name)
20
+ content_type :json
21
+ status response_code
22
+ headers "content-type"=>["application/json; charset=utf-8"]
23
+ erb File.open(File.dirname(__FILE__) + '/fake_musoni/' + file_name, 'rb').read
24
+ end
25
+ end
@@ -0,0 +1,173 @@
1
+ module Musoni::TestHelper
2
+ def create_musoni_client
3
+ client_attributes = {:officeId=>"2",
4
+ :firstname=> Faker::Name.first_name,
5
+ :staffId=>"1",
6
+ :lastname=> Faker::Name.last_name,
7
+ :middlename=> Faker::Name.first_name,
8
+ :externalId=>rand(100000),
9
+ :mobileNo=>"07234#{rand(10000)}",
10
+ :submittedOnDate=>"11-05-2015",
11
+ :active=>"true",
12
+ :activationDate=> Time.now.strftime("%d-%m-%Y")
13
+ }
14
+ @@musoni_client ||= Musoni::Client.create(client_attributes)
15
+ end
16
+
17
+ def create_musoni_loan
18
+ loan_options = {
19
+ :submittedOnDate=>"13-05-2015",
20
+ :clientId=>"3",
21
+ :productId=>"1",
22
+ :loanOfficerId=>"1",
23
+ :loanPurposeId=>"37",
24
+ :principal=>"10,000.00",
25
+ :loanTermFrequency=>"1",
26
+ :loanTermFrequencyType=>"2",
27
+ :numberOfRepayments=>"1",
28
+ :repaymentEvery=>"1",
29
+ :repaymentFrequencyType=>"2",
30
+ :transactionProcessingStrategyId=>"1",
31
+ :interestRatePerPeriod=>"5",
32
+ :expectedDisbursementDate=>"13-05-2015",
33
+ :amortizationType=>"1",
34
+ :interestType=>"1",
35
+ :interestCalculationPeriodType=>"1",
36
+ :inArrearsTolerance=>"0",
37
+ :interestChargedFromDate=>"13-05-2015",
38
+ :repaymentsStartingFromDate=>"13-06-2015",
39
+ :charges=>[],
40
+ :loanType=>"individual",
41
+ :linkAccountId=>"",
42
+ :graceOnPrincipalPayment=>"0",
43
+ :graceOnInterestCharged=>"0",
44
+ :graceOnInterestPayment=>"0",
45
+ :fundId=>"1",
46
+ :createStandingInstructionAtDisbursement=>false
47
+ }
48
+ @@musoni_loan ||= Musoni::Loan.create(loan_options)
49
+ end
50
+
51
+ def create_musoni_savings_account
52
+ account_options = {
53
+ :clientId=>"1",
54
+ :productId=>"1",
55
+ :submittedOnDate=>"13-05-2015",
56
+ :fieldOfficerId=>"1",
57
+ :charges=>[],
58
+ :allowOverdraft=>false
59
+ }
60
+ @@musoni_savings_account ||= Musoni::SavingsAccount.create(account_options)
61
+ end
62
+
63
+ [
64
+ :ml_client_details,
65
+ :cct_Borrower_Details,
66
+ :cct_TransUnion,
67
+ :cct_First_Access_Score
68
+ ]
69
+
70
+
71
+ def create_client_datatable
72
+ client = create_musoni_client
73
+ datatable_attributes = {
74
+ :MaritalStatus_cv_maritalStatus=>"Single",
75
+ :dateOfBirth=> Faker::Date.backward(10000).strftime("%d-%m-%Y"),
76
+ :Email=> Faker::Internet.email,
77
+ # :Password=> Faker::Internet.password,
78
+ :Client_Type=>"Lender",
79
+ :dateFormat=>"DD-MM-YYYY",
80
+ :locale=>"en_GB"
81
+ }
82
+ @@musoni_client_datatable ||= Musoni::Datatable.create(:ml_client_details,client.id,datatable_attributes)
83
+ end
84
+
85
+ def create_borrower_datatable
86
+ client = create_musoni_client
87
+ datatable_attributes = {
88
+ :town=>"Nairobi",
89
+ :address=>"Waiyaki Way",
90
+ :MaritalStatus_cv_maritalStatus=>"Single",
91
+ :dateOfBirth=>"01-01-1900",
92
+ :state=>"state",
93
+ :E_mail_address=> Faker::Internet.email,
94
+ :Password=> Faker::Internet.password,
95
+ :Sector=>"Sector1",
96
+ :occupation=>"Something",
97
+ :children_present=>"yes",
98
+ :household_size=>"10",
99
+ :dependants_no=>"5",
100
+ :household_assets=>"None",
101
+ :monthly_expense_food=>"100",
102
+ :monthly_expense_housing=>"500",
103
+ :monthly_expense_school=>"150",
104
+ :monthly_expense_medical=>"200",
105
+ :monthly_expense_tranport=>"230",
106
+ :monthly_expense_health=>"320",
107
+ :business_ownership=>"Yes",
108
+ :business_experience=>"10",
109
+ :book_keeping=>"yes",
110
+ :monthly_reorder_level=>"10",
111
+ :current_inventory_level=>"10",
112
+ :active_savings_devices=>"m-shwari,something else,3rd option",
113
+ :savings_emergency=>"1001",
114
+ :savings_school=>"1001",
115
+ :savings_asset=>"100",
116
+ :savings_entertainment=>"200",
117
+ :savings_medical=>"400",
118
+ :savings_business=>"500",
119
+ :savings_other=>"100",
120
+ :credit_limit_mshwari=>"100000000",
121
+ :saving_frequency=>"None",
122
+ :remittance_amount=>"1000",
123
+ :remittance_location=>"Yaya",
124
+ :remittance_frequency=>"daily",
125
+ :mobile_use=>"yes",
126
+ :last_mmoney_out=>"today",
127
+ :last_mmoney_in=>"yesterday",
128
+ :phones_owned=>"10",
129
+ :language_use=>"English,Dutch",
130
+ :data_mpesa=>"Mledger BLOB",
131
+ :income_weekly=>10000,
132
+ :survey_id=>123,
133
+ :dateFormat=>"dd-MM-yyyy",
134
+ :locale=>"en_GB"
135
+ }
136
+ @@musoni_borrower_datatable ||= Musoni::Datatable.create(:cct_Borrower_Details,client.id,datatable_attributes)
137
+ end
138
+
139
+ def create_transunion_datatable
140
+ client = create_musoni_client
141
+ datatable_attributes = {
142
+ :Credit_History=>"24",
143
+ :NPA_Accounts=>"1",
144
+ :NPA_Closed_Accounts=>"1",
145
+ :NPA_Open_Accounts=>"0",
146
+ :PA_Accounts=>"11",
147
+ :PA_Closed_Accounts=>"10",
148
+ :PA_Open_Accounts=>"1",
149
+ :Response_Statuscode=>"300",
150
+ :dateFormat=>"dd-MM-yyyy",
151
+ :locale=>"en_GB",
152
+ :submittedon_date=>"27-05-2015",
153
+ :submittedon_userid=>1
154
+ }
155
+ @@musoni_transunion_datatable ||= Musoni::Datatable.create(:cct_TransUnion,client.id,datatable_attributes)
156
+ end
157
+
158
+ def create_firstaccess_datatable
159
+ client = create_musoni_client
160
+ datatable_attributes = {
161
+ :Status=>"Approved",
162
+ :Risk_Bucket=>"Very Low",
163
+ :Loan_Size=>"10000",
164
+ :Interest_Rate=>"10.05",
165
+ :dateFormat=>"dd-MM-yyyy",
166
+ :locale=>"en_GB",
167
+ :submittedon_date=>"27-05-2015",
168
+ :submittedon_userid=>1
169
+ }
170
+ @@musoni_firstaccess_datatable ||= Musoni::Datatable.create(:cct_First_Access_Score,client.id,datatable_attributes)
171
+ end
172
+
173
+ end
@@ -0,0 +1,3 @@
1
+ module Musoni
2
+ VERSION = "0.0.01"
3
+ end
@@ -0,0 +1,54 @@
1
+ require "httparty"
2
+ require "hashie"
3
+ require "musoni_ruby/version"
4
+ require "musoni_ruby/configuration"
5
+ require "musoni_ruby/fetch"
6
+ require "musoni_ruby/endpoints/_endpoint"
7
+ require "musoni_ruby/endpoints/client"
8
+ require "musoni_ruby/endpoints/datatable"
9
+ require "musoni_ruby/endpoints/loan"
10
+ require "musoni_ruby/endpoints/run_report"
11
+ require "musoni_ruby/endpoints/savings_account"
12
+
13
+ # begin
14
+ # require "pry"
15
+ # require "pry-alias"
16
+ # rescue LoadError
17
+ # end
18
+
19
+ module Musoni
20
+ class << self
21
+ attr_writer :configuration
22
+
23
+ def configuration
24
+ @configuration ||= Configuration.new
25
+ end
26
+
27
+ def reset
28
+ @configuration = Configuration.new
29
+ end
30
+
31
+ def setup
32
+ yield(configuration)
33
+ end
34
+
35
+ # Musoni.authenticate(user:'username',password:"98497927493")
36
+ def authenticate(user:nil,password:nil,tenant:nil)
37
+ # bp
38
+ url = "/authentication?username=#{user}&password=#{password}&tenantIdentifier=#{tenant}"
39
+ request = Musoni::Fetch.post(url)
40
+ if (request.authenticated rescue false)
41
+ @configuration = Configuration.new(tenant:tenant, token:request.base64EncodedAuthenticationKey)
42
+ # @configuration.tenant = tenant
43
+ # @configuration.token = request.base64EncodedAuthenticationKey
44
+ # Musoni.setup do |config|
45
+ # config.tenant = tenant
46
+ # config.token = request.base64EncodedAuthenticationKey
47
+ # end
48
+ end
49
+ request
50
+ end
51
+ end
52
+
53
+ end
54
+
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'musoni_ruby/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "musoni_ruby"
8
+ spec.version = Musoni::VERSION
9
+ spec.authors = ["Kariuki Gathitu"]
10
+ spec.email = ["kgathi2@gmail.com"]
11
+
12
+ spec.summary = %q{Ruby Client for interfacing with Musoni systems API}
13
+ spec.description = %q{Railsesque may to integrate with Musoni systems}
14
+ spec.homepage = "https://bitbucket.org/kgathi2/musoni_ruby"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ # else
22
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ # end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+ spec.required_ruby_version = '~> 2.0'
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.9"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "guard", "~> 2.12"
34
+ spec.add_development_dependency "minitest", "~> 5.6"
35
+ spec.add_development_dependency "guard-minitest", "~> 2.4"
36
+ spec.add_development_dependency "minitest-reporters", "~> 1.0"
37
+ spec.add_development_dependency "pry", "~> 0.10"
38
+ spec.add_development_dependency "pry-nav", "~> 0.2"
39
+ spec.add_development_dependency "pry-alias", "~> 0.0"
40
+ spec.add_development_dependency "coveralls", '~> 0.8'
41
+ spec.add_development_dependency "webmock", '~> 1.21'
42
+ spec.add_development_dependency "sinatra", '~> 1.4'
43
+ spec.add_development_dependency "faker", '~> 1.4'
44
+
45
+ spec.add_dependency 'httparty', "~> 0.13"
46
+ spec.add_dependency 'hashie', "~> 3.4"
47
+ end