codat 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92ae19ae782d5a282bfe31ac82a20578fe5f69c7ddf3db320580e4d23af4a511
4
- data.tar.gz: c76eb6c58326f6bc12b8c6b2bdb622541e5dd93ac07c3e369af0d59b01004488
3
+ metadata.gz: c200bf7bf3b3702f186640149441c8cdb016b2078e374f8386da4f36d6d14a5a
4
+ data.tar.gz: 0b2409f51c5a5d6c49b3f477d8d9613a759071f207fcc0359f10b75a976b62af
5
5
  SHA512:
6
- metadata.gz: c4f2c95fb7cdd9c33f059ea0892af826e3c9b24aeec3f01a300fbf3633d4f7a1a4dad3d6b73680035ab0fd6b669e2d4aede3cb3e66ee8de5fe6153ad7ba4f68c
7
- data.tar.gz: 6548792832997f953b496bc7e108ea67f6efe334e45e06f81389ef8d6d9f29e1555bf387467b5fb72a40d0cf77c49089b920c6ca8b32c250140c213a6a0ae11d
6
+ metadata.gz: 2bb60e32a71c375260ad46d6da81505068b9a18dbdeb256674c204d56fcacd7797779109cf7c115a3fb1ce3e46d6c671df9358cf491cb9a8c15c0aa40902b71c
7
+ data.tar.gz: f8a0417775eefeefc554f593542f88d296e61f9dd614a015a45b1b72f3981218c6b461530f0960da6509c35d4558a4c9dc3b13d7be0d8d4b36d4ead46bc644f7
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ Gemfile.lock
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
data/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Codat
2
2
 
3
+ A simple wrapper for the [Codat](https://www.codat.io/) API. Please refer to Codat's documentation
4
+ to complement any information you need:
5
+
6
+ * [Codat API reference](https://docs.codat.io/)
7
+ * [Codat API explorer](https://api-uat.codat.io/swagger/ui/index) (to use this you need to have
8
+ access to the UAT portal).
9
+
3
10
  ## Installation
4
11
 
5
12
  Add this line to your application's Gemfile:
@@ -23,50 +30,50 @@ Or install it yourself as:
23
30
  To get a list of bank accounts:
24
31
 
25
32
  ```ruby
26
- list = BankAccount.all(company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac')
33
+ BankAccount.all(company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac')
27
34
  # => []
28
35
  ```
29
36
 
30
- ### Financial financials
37
+ ### Financial reports
31
38
 
32
- To get a financial reports - profit & loss:
39
+ To get a financial report - profit & loss:
33
40
 
34
41
  ```ruby
35
- list = Financial.profit_and_loss(
36
- company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac',
37
- period_length: '2',
38
- periods_to_compare: '2'
42
+ ProfitAndLoss.find(
43
+ company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac',
44
+ period_length: 12,
45
+ periods_to_compare: 2
39
46
  )
40
47
  # => []
41
48
  ```
42
49
 
43
- To get a financial reports - balance sheet:
50
+ To get a financial report - balance sheet:
44
51
 
45
52
  ```ruby
46
- list = BankAccount.balance_sheet(
47
- company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac',
48
- period_length: period_length,
49
- periods_to_compare: periods_to_compare
53
+ BalanceSheet.find(
54
+ company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac',
55
+ period_length: 12,
56
+ periods_to_compare: 2
50
57
  )
51
58
  ```
52
59
 
53
- ### Company companies
60
+ ### Companies
54
61
 
55
62
  To get a list of companies (paginated):
56
63
 
57
64
  ```ruby
58
- list = Company.all(page: '1')
65
+ Company.all(page: 1)
59
66
  # => []
60
67
  ```
61
68
 
62
69
  To create a company:
63
70
 
64
71
  ```ruby
65
- response = Company.create(name: 'company name')
72
+ Company.create(name: 'company name')
66
73
  # => {}
67
74
  ```
68
75
 
69
- ### Report reports
76
+ ### Report
70
77
 
71
78
  To get a list of reports for aged debtor:
72
79
 
@@ -75,7 +82,7 @@ list = Report.all(company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac')
75
82
  # => []
76
83
  ```
77
84
 
78
- ### BankStatement bankStatements
85
+ ### BankStatement
79
86
 
80
87
  To get a list of bank statements:
81
88
 
@@ -86,9 +93,14 @@ list = BankStatement.all(company_id: 'a49b891d-a593-43aa-bb82-0d8b108eb3ac')
86
93
 
87
94
  ## Development
88
95
 
89
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
96
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
97
+ the tests. You can also run `bin/console` for an interactive prompt that will allow you to
98
+ experiment.
90
99
 
91
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
100
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new
101
+ version, update the version number in `version.rb`, and then run `bundle exec rake release`, which
102
+ will create a git tag for the version, push git commits and tags, and push the `.gem` file to
103
+ [rubygems.org](https://rubygems.org).
92
104
 
93
105
  ## Contributing
94
106
 
@@ -5,10 +5,11 @@ require 'codat/configuration'
5
5
  require 'codat/client'
6
6
 
7
7
  require 'codat/models/bank_account'
8
- require 'codat/models/financial'
9
8
  require 'codat/models/company'
10
9
  require 'codat/models/report'
11
10
  require 'codat/models/bank_statement'
11
+ require 'codat/models/balance_sheet'
12
+ require 'codat/models/profit_and_loss'
12
13
 
13
14
  module Codat
14
15
  module_function
@@ -7,9 +7,6 @@ module Codat
7
7
  class GenericError < StandardError
8
8
  end
9
9
 
10
- class CompanyNotProvidedError < StandardError
11
- end
12
-
13
10
  class InvalidRequestError < StandardError
14
11
  end
15
12
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'codat/base_model'
4
+ require 'codat/models/balance_sheet_report'
5
+ require 'codat/models/financial_sheet'
6
+
7
+ module Codat
8
+ module Models
9
+ class BalanceSheet < FinancialSheet
10
+ endpoint '/companies/:company_id/data/financials/balanceSheet'
11
+
12
+ # attributes :currency, :most_recent_available_month, :earliest_available_month
13
+
14
+ report_class BalanceSheetReport
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'codat/base_model'
5
+ require 'codat/models/report_item'
6
+
7
+ module Codat
8
+ module Models
9
+ class BalanceSheetReport < BaseModel
10
+ attributes :date, :net_assets
11
+
12
+ attr_accessor :assets, :liabilities, :equity
13
+
14
+ def initialize(json: {})
15
+ super
16
+
17
+ @assets = ReportItem.new(json: json.fetch(:assets, {}))
18
+ @liabilities = ReportItem.new(json: json.fetch(:liabilities, {}))
19
+ @equity = ReportItem.new(json: json.fetch(:equity, {}))
20
+ end
21
+
22
+ def date
23
+ Date.parse(@date)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -6,21 +6,23 @@ module Codat
6
6
  module Models
7
7
  # Bank statements for a given company.
8
8
  class BankStatement < BaseModel
9
- ENDPOINT = '/companies/:company_id/data/bankStatements/accounts'
9
+ ENDPOINT = '/companies/:company_id/data/bankStatements'
10
10
 
11
11
  attributes :id, :date, :description, :reconciled, :amount, :balance, :transaction_type
12
12
  attributes :modified_date, :source_modifiedDate
13
13
 
14
- def self.all(company_id:)
15
- url = format_url(
16
- ENDPOINT, company_id: company_id.to_s.strip
17
- )
14
+ def self.all(company_id:, account_id:, page: 1)
15
+ url = format_url(ENDPOINT, company_id: company_id.to_s.strip)
18
16
 
19
- result = get(url)
17
+ result = get(url, accountId: account_id.to_s.strip, page: page.to_s.strip)
20
18
 
21
19
  return [] if result.status == 404
22
20
 
23
- result.body.map { |bank_statement| new(json: bank_statement) }
21
+ records = result.body.dig(:results)
22
+
23
+ return [] unless records
24
+
25
+ records.map { |bank_statement| new(json: bank_statement) }
24
26
  end
25
27
  end
26
28
  end
@@ -6,13 +6,17 @@ module Codat
6
6
  module Models
7
7
  # Companies for a given company.
8
8
  class Company < BaseModel
9
- ENDPOINT = '/companies'
9
+ ENDPOINTS = {
10
+ collection: '/companies',
11
+ single: '/companies/:company_id'
12
+ }.freeze
10
13
 
11
14
  attributes :id, :name, :platform, :redirect, :status, :last_sync, :data_connections
12
15
  attributes :integration_id, :source_id, :platform_name, :link_url
13
16
 
17
+ # Returns the list of companies in the Codat account.
14
18
  def self.all(params = {})
15
- result = get(ENDPOINT, params)
19
+ result = get(ENDPOINTS[:collection], params)
16
20
 
17
21
  return [] if result.status == 404
18
22
 
@@ -21,10 +25,18 @@ module Codat
21
25
  result.body[:results].map { |company| new(json: company) }
22
26
  end
23
27
 
24
- def self.create(params = {})
25
- url = format_url(ENDPOINT, {})
28
+ def self.find(company_id)
29
+ url = format_url(ENDPOINTS[:single], company_id: company_id)
30
+
31
+ result = get(url)
26
32
 
27
- result = post(url, params)
33
+ return nil if result.status == 404
34
+
35
+ new(json: result.body)
36
+ end
37
+
38
+ def self.create(params = {})
39
+ result = post(ENDPOINTS[:collection], params)
28
40
 
29
41
  return { error: 'An error occured.' } if result.status == 404 || result.status == 400
30
42
 
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ module Codat
6
+ module Models
7
+ class FinancialSheet < BaseModel
8
+ # Default period length (months)
9
+ DEFAULT_PERIOD_LENGTH = 12
10
+
11
+ # Default number of periods to compare
12
+ DEFAULT_PERIODS_TO_COMPARE = 2
13
+
14
+ attr_reader :reports
15
+
16
+ def self.inherited(other)
17
+ other.attributes :currency, :most_recent_available_month, :earliest_available_month
18
+ end
19
+
20
+ # Finds the latest financial sheet for a company. This can be a balance sheet or a profit and
21
+ # loss document.
22
+ #
23
+ # Params are listed below:
24
+ # * company_id - the company ID from Codat
25
+ # * period_length - the number of months to get
26
+ # * periods_to_compare - how many periods (of period_length size) you want
27
+ # * start_month (optional) - starting in which month (date)
28
+ #
29
+ # An ArgumentError is raised unless you provide a :company_id key in the params.
30
+ def self.find(params = {})
31
+ company_id = params.dig(:company_id)
32
+
33
+ raise ArgumentError, 'please provide company_id' unless company_id
34
+
35
+ url = format_url(@endpoint, company_id: company_id.to_s.strip)
36
+
37
+ result = get(url, build_query(params))
38
+
39
+ return nil if result.status == 404 || result.status == 400
40
+
41
+ new(json: result.body)
42
+ end
43
+
44
+ def self.build_query(params)
45
+ options = params.dup
46
+
47
+ query = {
48
+ periodLength: options.fetch(:period_length, DEFAULT_PERIOD_LENGTH),
49
+ periodsToCompare: options.fetch(:periods_to_compare, DEFAULT_PERIODS_TO_COMPARE)
50
+ }
51
+
52
+ options = options.map { |key, value| [Camelizer.transform(key), value] }.to_h
53
+
54
+ query.merge(options)
55
+ end
56
+
57
+ def self.report_class(report_class = nil)
58
+ return @report_class unless report_class
59
+
60
+ @report_class = report_class
61
+ end
62
+
63
+ def self.endpoint(endpoint = nil)
64
+ return @endpoint unless endpoint
65
+
66
+ @endpoint = endpoint
67
+ end
68
+
69
+ def initialize(json: {})
70
+ super
71
+
72
+ @most_recent_available_month = Date.parse(json.dig(:mostRecentAvailableMonth))
73
+ @earliest_available_month = Date.parse(json.dig(:earliestAvailableMonth))
74
+
75
+ reports_json = json.fetch(:reports, {})
76
+ @reports = reports_json.map { |report| self.class.report_class.new(json: report) }
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'codat/base_model'
4
+ require 'codat/models/profit_and_loss_report'
5
+ require 'codat/models/financial_sheet'
6
+
7
+ module Codat
8
+ module Models
9
+ class ProfitAndLoss < FinancialSheet
10
+ endpoint '/companies/:company_id/data/financials/profitAndLoss'
11
+
12
+ attributes :report_basis
13
+
14
+ report_class ProfitAndLossReport
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'codat/base_model'
5
+ require 'codat/models/report_item'
6
+
7
+ module Codat
8
+ module Models
9
+ class ProfitAndLossReport < BaseModel
10
+ attributes :from_date, :to_date, :gross_profit, :net_other_income, :net_profit
11
+ attributes :net_operating_profit
12
+
13
+ attr_accessor :income, :cost_of_sales, :expenses, :other_expenses, :other_income
14
+
15
+ def initialize(json: {})
16
+ super
17
+
18
+ @from_date = Date.parse(json.fetch(:fromDate))
19
+ @to_date = Date.parse(json.fetch(:toDate))
20
+
21
+ @income = ReportItem.new(json: json.fetch(:income, {}))
22
+ @cost_of_sales = ReportItem.new(json: json.fetch(:costOfSales, {}))
23
+ @expenses = ReportItem.new(json: json.fetch(:expenses, {}))
24
+ @other_expenses = ReportItem.new(json: json.fetch(:otherExpenses, {}))
25
+ @other_income = ReportItem.new(json: json.fetch(:otherIncome, {}))
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'codat/base_model'
4
+
5
+ module Codat
6
+ module Models
7
+ # A report item can be present in BalanceSheetReport or ProfitAndLossReport.
8
+ class ReportItem < BaseModel
9
+ attributes :account_id, :name, :value
10
+
11
+ attr_accessor :items
12
+
13
+ def initialize(json: {})
14
+ super
15
+
16
+ # The items can have an array of items inside. It's weird, but this happens a lot.
17
+ items_json = json.fetch(:items, [])
18
+ @items = items_json.map { |item| ReportItem.new(json: item) }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Codat
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ricardo Otero
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-09-29 00:00:00.000000000 Z
11
+ date: 2018-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -233,7 +233,6 @@ files:
233
233
  - ".rubocop.yml"
234
234
  - ".travis.yml"
235
235
  - Gemfile
236
- - Gemfile.lock
237
236
  - LICENSE.txt
238
237
  - README.md
239
238
  - Rakefile
@@ -247,11 +246,16 @@ files:
247
246
  - lib/codat/configuration.rb
248
247
  - lib/codat/errors.rb
249
248
  - lib/codat/faraday_codat_auth.rb
249
+ - lib/codat/models/balance_sheet.rb
250
+ - lib/codat/models/balance_sheet_report.rb
250
251
  - lib/codat/models/bank_account.rb
251
252
  - lib/codat/models/bank_statement.rb
252
253
  - lib/codat/models/company.rb
253
- - lib/codat/models/financial.rb
254
+ - lib/codat/models/financial_sheet.rb
255
+ - lib/codat/models/profit_and_loss.rb
256
+ - lib/codat/models/profit_and_loss_report.rb
254
257
  - lib/codat/models/report.rb
258
+ - lib/codat/models/report_item.rb
255
259
  - lib/codat/version.rb
256
260
  homepage: https://gitlab.com/finpoint/codat
257
261
  licenses:
@@ -1,104 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- codat (0.1.1)
5
- faraday (~> 0.15)
6
- faraday_middleware (~> 0.12)
7
- faraday_middleware-multi_json (~> 0.0.6)
8
- multi_json (~> 1.13)
9
- rainbow (~> 3.0)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- addressable (2.5.2)
15
- public_suffix (>= 2.0.2, < 4.0)
16
- ast (2.4.0)
17
- byebug (10.0.2)
18
- coderay (1.1.2)
19
- crack (0.4.3)
20
- safe_yaml (~> 1.0.0)
21
- diff-lcs (1.3)
22
- docile (1.3.1)
23
- dotenv (2.5.0)
24
- faraday (0.15.3)
25
- multipart-post (>= 1.2, < 3)
26
- faraday_middleware (0.12.2)
27
- faraday (>= 0.7.4, < 1.0)
28
- faraday_middleware-multi_json (0.0.6)
29
- faraday_middleware
30
- multi_json
31
- hashdiff (0.3.7)
32
- jaro_winkler (1.5.1)
33
- json (2.1.0)
34
- method_source (0.9.0)
35
- multi_json (1.13.1)
36
- multipart-post (2.0.0)
37
- parallel (1.12.1)
38
- parser (2.5.1.2)
39
- ast (~> 2.4.0)
40
- powerpack (0.1.2)
41
- pry (0.11.3)
42
- coderay (~> 1.1.0)
43
- method_source (~> 0.9.0)
44
- pry-byebug (3.6.0)
45
- byebug (~> 10.0)
46
- pry (~> 0.10)
47
- public_suffix (3.0.3)
48
- rainbow (3.0.0)
49
- rake (10.5.0)
50
- rspec (3.8.0)
51
- rspec-core (~> 3.8.0)
52
- rspec-expectations (~> 3.8.0)
53
- rspec-mocks (~> 3.8.0)
54
- rspec-core (3.8.0)
55
- rspec-support (~> 3.8.0)
56
- rspec-expectations (3.8.1)
57
- diff-lcs (>= 1.2.0, < 2.0)
58
- rspec-support (~> 3.8.0)
59
- rspec-mocks (3.8.0)
60
- diff-lcs (>= 1.2.0, < 2.0)
61
- rspec-support (~> 3.8.0)
62
- rspec-support (3.8.0)
63
- rubocop (0.59.2)
64
- jaro_winkler (~> 1.5.1)
65
- parallel (~> 1.10)
66
- parser (>= 2.5, != 2.5.1.1)
67
- powerpack (~> 0.1)
68
- rainbow (>= 2.2.2, < 4.0)
69
- ruby-progressbar (~> 1.7)
70
- unicode-display_width (~> 1.0, >= 1.0.1)
71
- rubocop-rspec (1.29.1)
72
- rubocop (>= 0.58.0)
73
- ruby-progressbar (1.10.0)
74
- safe_yaml (1.0.4)
75
- simplecov (0.16.1)
76
- docile (~> 1.1)
77
- json (>= 1.8, < 3)
78
- simplecov-html (~> 0.10.0)
79
- simplecov-html (0.10.2)
80
- unicode-display_width (1.4.0)
81
- vcr (4.0.0)
82
- webmock (3.4.2)
83
- addressable (>= 2.3.6)
84
- crack (>= 0.3.2)
85
- hashdiff
86
-
87
- PLATFORMS
88
- ruby
89
-
90
- DEPENDENCIES
91
- bundler (~> 1.16)
92
- codat!
93
- dotenv (~> 2.5)
94
- pry-byebug (~> 3.6)
95
- rake (~> 10.0)
96
- rspec (~> 3.0)
97
- rubocop (~> 0.58)
98
- rubocop-rspec (~> 1.27)
99
- simplecov (~> 0.16)
100
- vcr (~> 4.0.0)
101
- webmock (~> 3.4.2)
102
-
103
- BUNDLED WITH
104
- 1.16.1
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'codat/base_model'
4
-
5
- module Codat
6
- module Models
7
- # Financials for a given company.
8
- class Financial < BaseModel
9
- ENDPOINT = {
10
- profit_and_loss: '/companies/:company_id/data/financials/profitAndLoss',
11
- balance_sheet: '/companies/:company_id/data/financials/balanceSheet'
12
- }.freeze
13
-
14
- attributes :from_date, :to_date, :income, :account_id, :name, :value, :items
15
- attributes :cost_of_sales, :gross_profit, :expenses, :net_operating_profit, :other_expenses
16
- attributes :other_income, :net_other_income, :net_profit
17
-
18
- def self.profit_and_loss(params = {})
19
- company_id = params.delete(:company_id)
20
-
21
- raise CompanyNotProvidedError if company_id.nil? || company_id.empty?
22
-
23
- url = format_url(
24
- ENDPOINT[:profit_and_loss],
25
- company_id: company_id.to_s.strip
26
- )
27
-
28
- params = params.map { |key, value| [Camelizer.transform(key), value] }.to_h
29
-
30
- result = get(url, params)
31
-
32
- return [] if result.status == 404 || result.status == 400
33
-
34
- result.body[:reports].map { |report| new(json: report) }
35
- end
36
-
37
- def self.balance_sheet(params = {})
38
- company_id = params.delete(:company_id)
39
-
40
- raise CompanyNotProvidedError if company_id.nil? || company_id.empty?
41
-
42
- url = format_url(
43
- ENDPOINT[:balance_sheet],
44
- company_id: company_id.to_s.strip
45
- )
46
-
47
- params.delete(:company_id)
48
- params = params.map { |key, value| [Camelizer.transform(key), value] }.to_h
49
-
50
- result = get(url, params)
51
-
52
- return [] if result.status == 404 || result.status == 400
53
-
54
- result.body[:reports].map { |report| new(json: report) }
55
- end
56
- end
57
- end
58
- end