comptaline 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1e200a81d1459c390b6255aeb4464f37d0dc0f2b
4
+ data.tar.gz: 109fe810b268b9a4c5cb26223b21965653bcb5bd
5
+ SHA512:
6
+ metadata.gz: 0d6602d037f9c87ac94deb793ac756c242b510d050892d1d08bf5d1221530d30c1516e7e624edde8c0115a588e4f6dfbf9e278d4b361563c3a2eb3a38bf2ba24
7
+ data.tar.gz: bfe85aeb1ba473a7404efaf9c43ee39e0c85d0ffe86880ec7f16950b5549c79c49fa472cb85326d38004343d17a81f4cc4a5fba5967b449e16bb76495f4f9b84
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENCE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Loïc Vigneron
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Comptaline
2
+
3
+ A Comptaline ( http://comptaline.be )
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'comptaline'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install comptaline
20
+
21
+ ## Usage
22
+
23
+ Add this in an initializer:
24
+
25
+ ```ruby
26
+ Comptaline.configure do | configuration |
27
+ configuration.host_url = "https://www.comptamanager.be/app/"
28
+ configuration.username = "<user>"
29
+ configuration.password = "<password>"
30
+ configuration.invoice_journal = "<INVJOURNAL>"
31
+ configuration.credit_note_journal = "<NCJOURNAL>"
32
+ end
33
+ ```
34
+
35
+ Then create accounting entries and append them to the exporter instance:
36
+
37
+ ```ruby
38
+ exporter = Comptaline::Exporter.new
39
+
40
+ customer = Comptaline::AccountingEntry::Customer.new
41
+ customer.first_name = "Bob"
42
+ customer.id = 1
43
+ exporter.push(customer)
44
+
45
+ invoice = Comptaline::AccountingEntry::Invoice.new
46
+ invoice.customer_id = customer_id
47
+ invoice.invoice_number = 100
48
+ exporter.push(invoice)
49
+
50
+ exporter.flush!
51
+ ```
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it ( https://github.com/spin42/comptaline/fork )
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "comptaline/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "comptaline"
8
+ spec.version = Comptaline::VERSION
9
+ spec.authors = ["Spin42"]
10
+ spec.email = ["info@spin42.com"]
11
+ spec.summary = "Client gem for Comptaline API"
12
+ spec.description = "Client gem for Comptaline API"
13
+ spec.homepage = "https://github.com/Spin42/comptaline"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_dependency "rest-client", "~> 1.7"
24
+ end
data/lib/comptaline.rb ADDED
@@ -0,0 +1,33 @@
1
+ require "rest-client"
2
+ require "uri"
3
+ require "csv"
4
+
5
+ require_relative "comptaline/client"
6
+ require_relative "comptaline/exporter"
7
+ require_relative "comptaline/utils"
8
+ require_relative "comptaline/accounting_entry/base"
9
+ require_relative "comptaline/accounting_entry/general_operation"
10
+ require_relative "comptaline/accounting_entry/customer"
11
+ require_relative "comptaline/accounting_entry/invoice"
12
+ require_relative "comptaline/accounting_entry/clearance"
13
+
14
+ module Comptaline
15
+ class Configuration
16
+ attr_accessor :host_url, :username, :password, :invoice_journal, :credit_note_journal,
17
+ :invoicer_subject_to_vat, :tmp_dir
18
+ end
19
+
20
+ @configuration = Configuration.new
21
+
22
+ def self.configure(&block)
23
+ yield(@configuration)
24
+ end
25
+
26
+ def self.configuration
27
+ @configuration
28
+ end
29
+
30
+ def self.client
31
+ @client ||= Comptaline::Client.new @configuration
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ module Comptaline
2
+ module AccountingEntry
3
+ class Base
4
+ def format_date(date)
5
+ date.strftime("%d/%m/%y")
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ module Comptaline
2
+ module AccountingEntry
3
+ class Clearance < GeneralOperation
4
+ def to_a
5
+ [
6
+ action,
7
+ operation_type,
8
+ @reference,
9
+ @amount,
10
+ format_date(@date),
11
+ @communication,
12
+ @currency_code,
13
+ @accounting_journal,
14
+ @match_id,
15
+ @accounting_writing_number,
16
+ @index
17
+ ]
18
+ end
19
+
20
+ private
21
+
22
+ def action
23
+ "2"
24
+ end
25
+
26
+ def operation_type
27
+ "C"
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,62 @@
1
+ module Comptaline
2
+ module AccountingEntry
3
+ class Customer < Base
4
+ attr_accessor :id, :language_code, :first_name, :last_name, :street, :zipcode, :city, :country_code, :phone_number, :vat_number, :iban, :bic, :email,
5
+ :fax_number, :category, :civility, :company_name, :company_civility
6
+
7
+ def to_a
8
+ [
9
+ action,
10
+ @id,
11
+ client_type,
12
+ @language_code,
13
+ formatted_company_name,
14
+ @company_civility,
15
+ name,
16
+ @civility,
17
+ @category,
18
+ @street,
19
+ formatted_zipcode,
20
+ @city,
21
+ @country_code,
22
+ @phone_number,
23
+ @fax_number,
24
+ formatted_vat_number,
25
+ @iban,
26
+ @bic,
27
+ @email
28
+ ]
29
+ end
30
+
31
+ private
32
+
33
+ def name
34
+ name = @last_name
35
+ name = "#{name} #{@first_name}" if @first_name
36
+ name
37
+ end
38
+
39
+ def action
40
+ 3
41
+ end
42
+
43
+ def client_type
44
+ 1
45
+ end
46
+
47
+ def formatted_zipcode
48
+ return nil if @zipcode.nil?
49
+ "#{@country_code}-#{@zipcode}"
50
+ end
51
+
52
+ def formatted_company_name
53
+ @company_name || name
54
+ end
55
+
56
+ def formatted_vat_number
57
+ return nil unless @vat_number
58
+ @vat_number.gsub(/\D/, "")
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,24 @@
1
+ module Comptaline
2
+ module AccountingEntry
3
+ class GeneralOperation < Base
4
+ attr_accessor :action, :operation_type, :reference, :amount, :date, :communication, :currency_code,
5
+ :accounting_journal, :match_id, :accounting_writing_number, :index
6
+
7
+ def to_a
8
+ [
9
+ @action,
10
+ @operation_type,
11
+ @reference,
12
+ @amount,
13
+ format_date(@date),
14
+ @communication,
15
+ @currency_code,
16
+ @accounting_journal,
17
+ @match_id,
18
+ @accounting_writing_number,
19
+ @index
20
+ ]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,133 @@
1
+ module Comptaline
2
+ module AccountingEntry
3
+ class Invoice < Base
4
+ attr_accessor :customer, :is_credit_note, :date, :due_date, :invoice_number, :communication, :structured_communication, :account_assignment,
5
+ :vat_code, :amount, :amount_with_vat, :vat_amount, :currency_code, :match_id
6
+
7
+ def initialize(type = {})
8
+ @is_credit_note = type[:is_credit_note] == true
9
+ end
10
+
11
+ def to_a
12
+ [
13
+ action,
14
+ @customer.id,
15
+ journal,
16
+ period,
17
+ invoice_number,
18
+ format_date(@date),
19
+ format_date(@due_date),
20
+ @communication,
21
+ @structured_communication,
22
+ account_assignment,
23
+ vat_code,
24
+ @amount,
25
+ @vat_amount,
26
+ @amount_with_vat,
27
+ @currency_code,
28
+ @match_id,
29
+ credit_note_flag
30
+ ]
31
+ end
32
+
33
+ def vat_code
34
+ return @vat_code unless @vat_code.nil?
35
+ vat_codes[invoice_type]
36
+ end
37
+
38
+ def account_assignment
39
+ return @account_assignment unless @account_assignment.nil?
40
+ account_assignments[invoice_type]
41
+ end
42
+
43
+ private
44
+
45
+ def action
46
+ 1
47
+ end
48
+
49
+ def journal
50
+ if @is_credit_note
51
+ Comptaline.configuration.credit_note_journal
52
+ else
53
+ Comptaline.configuration.invoice_journal
54
+ end
55
+ end
56
+
57
+ def credit_note_flag
58
+ @is_credit_note ? 1 : 0
59
+ end
60
+
61
+ def period
62
+ @date.strftime("%m")
63
+ end
64
+
65
+ def invoice_type
66
+ if !Comptaline.configuration.invoicer_subject_to_vat
67
+ :invoicer_not_subject_to_vat
68
+ elsif @customer.country_code == "BE"
69
+ :belgian_customer
70
+ elsif @customer.vat_number
71
+ :european_business_customer
72
+ elsif vat_codes_for_european_countries[@customer.country_code]
73
+ :european_individual_customer
74
+ else
75
+ :non_european_customer
76
+ end
77
+ end
78
+
79
+ def account_assignments
80
+ {
81
+ invoicer_not_subject_to_vat: "702100",
82
+ belgian_customer: "702100",
83
+ european_business_customer: "700001",
84
+ european_individual_customer: "700003",
85
+ non_european_customer: "700002"
86
+ }
87
+ end
88
+
89
+ def vat_codes
90
+ {
91
+ invoicer_not_subject_to_vat: "211100",
92
+ belgian_customer: "211400",
93
+ european_business_customer: "222000",
94
+ european_individual_customer: vat_codes_for_european_countries[@customer.country_code],
95
+ non_european_customer: "232000"
96
+ }
97
+ end
98
+
99
+ def vat_codes_for_european_countries
100
+ {
101
+ "AT" => "224100",
102
+ "BG" => "225500",
103
+ "BE" => "211400",
104
+ "CY" => "224600",
105
+ "DE" => "232002",
106
+ "DK" => "223100",
107
+ "ES" => "223300",
108
+ "EE" => "224500",
109
+ "FI" => "224300",
110
+ "FR" => "223405",
111
+ "GR" => "223200",
112
+ "UK" => "223500",
113
+ "HU" => "224900",
114
+ "IE" => "223600",
115
+ "IT" => "223700",
116
+ "LV" => "224700",
117
+ "LT" => "224800",
118
+ "LU" => "223800",
119
+ "MT" => "225000",
120
+ "NL" => "223902",
121
+ "PL" => "225100",
122
+ "PT" => "224000",
123
+ "RO" => "225400",
124
+ "SK" => "225300",
125
+ "SI" => "225200",
126
+ "SE" => "224200",
127
+ "CZ" => "224400",
128
+ "HR" => "225600"
129
+ }
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,63 @@
1
+ require "securerandom"
2
+
3
+ module Comptaline
4
+ class Client
5
+ attr_accessor :host_url, :username, :password
6
+
7
+ def initialize(configuration)
8
+ @host_url = configuration.host_url
9
+ @username = configuration.username
10
+ @password = configuration.password
11
+ end
12
+
13
+ def send(csv)
14
+ file = make_file_for_multipart(csv)
15
+ begin
16
+ authenticated_request(:post, "OPERATIONS", { choice: "CSV" }, { fileName: file})
17
+ ensure
18
+ File.unlink(file.path)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def make_file_for_multipart(csv)
25
+ dir = Comptaline.configuration.tmp_dir
26
+ path = File.join(dir, "comptaline_#{SecureRandom.hex}.csv")
27
+ File.open(path, "w:ISO-8859-1") { |file| file.write(csv) }
28
+ File.new(path, :mode => "rb")
29
+ end
30
+
31
+ def authenticated_request(method, path, params = {}, payload = {})
32
+ open_session
33
+ params.merge!(sessionid: @session_id)
34
+ result = request(method, path, params, payload)
35
+ close_session
36
+ result
37
+ end
38
+
39
+ def open_session
40
+ result = request(:get, "SESSION", choice: 1, username: @username, password: @password)
41
+ @session_id = result["sessionid"]
42
+ end
43
+
44
+ def close_session
45
+ request(:get, "SESSION", choice: 2, sessionid: @session_id)
46
+ end
47
+
48
+ def request(method, path, params = {}, payload = {})
49
+ uri = URI.join(@host_url, path)
50
+ uri.query = URI.encode_www_form(params)
51
+
52
+ RestClient.__send__(method, uri.to_s, payload) do |body, request, response|
53
+ throw "Error while retreiving data #{body.inspect}" unless response.code == "200"
54
+ result = Hash.from_xml(body)["response"]
55
+ if result["status"] != "0"
56
+ throw "Something went wrong: #{path}, #{params}, #{result}"
57
+ else
58
+ result
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ module Comptaline
2
+ class Exporter
3
+ def initialize
4
+ @entries_buffer = []
5
+ end
6
+
7
+ def concat(entries)
8
+ @entries_buffer.concat(entries)
9
+ end
10
+
11
+ def push(entry)
12
+ @entries_buffer.push(entry)
13
+ end
14
+
15
+ def flush!(options = {})
16
+ return "" unless @entries_buffer.size > 0
17
+
18
+ csv = CSV.generate(col_sep: ";", row_sep: "\n", encoding: "iso-8859-1") do |csv|
19
+ @entries_buffer.each do |entry|
20
+ csv << encode(entry.to_a)
21
+ end
22
+ end
23
+ Comptaline.client.send(csv) if options[:send] == true
24
+ csv
25
+ end
26
+
27
+ def add_customer(customer)
28
+ add_line(customer)
29
+ end
30
+
31
+ def add_invoice(invoice)
32
+ add_line(invoice)
33
+ end
34
+
35
+ private
36
+
37
+ def add_line(object)
38
+ buffer.push(object.to_a)
39
+ end
40
+
41
+ def encode(values)
42
+ values.map do |value|
43
+ if value.respond_to?(:encode)
44
+ value.encode("iso-8859-1").gsub(/["']/, " ")
45
+ else
46
+ value
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+ module Comptaline
2
+ class Utils
3
+ def self.convert_to_match_id(integer)
4
+ integer % 1000000000
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Comptaline
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: comptaline
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Spin42
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ description: Client gem for Comptaline API
56
+ email:
57
+ - info@spin42.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENCE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - comptaline.gemspec
68
+ - lib/comptaline.rb
69
+ - lib/comptaline/accounting_entry/base.rb
70
+ - lib/comptaline/accounting_entry/clearance.rb
71
+ - lib/comptaline/accounting_entry/customer.rb
72
+ - lib/comptaline/accounting_entry/general_operation.rb
73
+ - lib/comptaline/accounting_entry/invoice.rb
74
+ - lib/comptaline/client.rb
75
+ - lib/comptaline/exporter.rb
76
+ - lib/comptaline/utils.rb
77
+ - lib/comptaline/version.rb
78
+ homepage: https://github.com/Spin42/comptaline
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.2.2
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Client gem for Comptaline API
102
+ test_files: []