musoni_ruby 0.0.01

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