africompta 1.9.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ class Schema_Infos < Entities
2
+ def setup_data
3
+ @default_type = :SQLiteAC
4
+ @data_field_id = :id
5
+
6
+ value_str :version
7
+ end
8
+
9
+ def migration_1(s)
10
+ s.version = '0.4'
11
+ end
12
+
13
+ def migration_2(s)
14
+ s.version = '0.5'
15
+ end
16
+ end
@@ -0,0 +1,292 @@
1
+ DEBUG_SLOW=4
2
+ class Movements < Entities
3
+ attr_reader :check_state, :check_progress
4
+
5
+ def setup_data
6
+ @default_type = :SQLiteAC
7
+ @data_field_id = :id
8
+ value_int :index
9
+
10
+ value_entity_account :account_src_id
11
+ value_entity_account :account_dst_id
12
+ value_float :value
13
+ value_str :desc
14
+ value_date :date
15
+ value_int :revision
16
+ value_str :global_id
17
+ value_int :rev_index
18
+ end
19
+
20
+ def migration_1(m)
21
+ dputs(1) { "Migrating #{m.id}" }
22
+ m.rev_index = m.id
23
+ end
24
+
25
+ def self.from_json(str)
26
+ self.from_s(ActiveSupport::JSON.decode(str)['str'])
27
+ end
28
+
29
+ def self.get_accounts(src, dst)
30
+ [Accounts.match_by_global_id(src), Accounts.match_by_global_id(dst)]
31
+ end
32
+
33
+ def self.mbgi(global_id)
34
+ self.match_by_global_id(global_id)
35
+ end
36
+
37
+ def self.from_s(str)
38
+ str.force_encoding(Encoding::UTF_8)
39
+ dputs(3) { "Getting movement from #{str.inspect}" }
40
+ desc, str = str.split("\r")
41
+ global_id, value, date, src, dst = str.split("\t")
42
+ #date = Time.parse(date).to_ss
43
+ date = Date.strptime(date, '%Y-%m-%d')
44
+ value = value.to_f
45
+ a_src, a_dst = self.get_accounts(src, dst)
46
+ if not a_src or not a_dst
47
+ dputs(0) { "Couldn't parse #{str.inspect}: " +
48
+ (a_src ? '' : "account #{src} not found. ") +
49
+ (a_dst ? '' : "account #{dst} not found") }
50
+ return nil
51
+ end
52
+ # Does the movement already exist?
53
+ dputs(DEBUG_SLOW) { 'from_s 1'
54
+ }
55
+ our_m = nil
56
+ if not (our_m = self.mbgi(global_id))
57
+ dputs(3) { 'New movement' }
58
+ our_m = self.create(desc, date, value,
59
+ a_src, a_dst)
60
+ dputs(DEBUG_SLOW) { 'from_s 2' }
61
+ our_m.global_id = global_id
62
+ else
63
+ dputs(1) { "Overwriting movement\n#{our_m.to_json.inspect} with" }
64
+ # And update it
65
+ our_m.set(desc, date, value, a_src.id, a_dst.id)
66
+ dputs(1) { "#{our_m.to_json.inspect}" }
67
+ dputs(2) { "Now we're #{our_m.rev_index}:#{our_m.id} -> #{global_id}" }
68
+ end
69
+ dputs(DEBUG_SLOW) { 'from_s 3' }
70
+ return our_m
71
+ end
72
+
73
+ def create(desc, date, value, source, dest)
74
+ return nil if source == dest
75
+ dputs(DEBUG_SLOW) { 'create - 1' }
76
+ if date.class == String
77
+ date = Date.strptime(date, '%Y-%m-%d')
78
+ end
79
+ t = super(:desc => desc, :date => date,
80
+ :value => 0, :account_src_id => source.id, :account_dst_id => dest.id)
81
+ dputs(DEBUG_SLOW) { 'create - 2' }
82
+ t.value = value
83
+ dputs(DEBUG_SLOW) { 'create - 3' }
84
+ t.global_id = Users.match_by_name('local').full + '-' + t.id.to_s
85
+ dputs(DEBUG_SLOW) { 'create - 4' }
86
+ dputs(1) { "Created #{t.to_json.inspect}" }
87
+ t
88
+ end
89
+
90
+ def search_index_range(from, to)
91
+ @data.select { |k, v|
92
+ v._rev_index && v._rev_index >= from && v._rev_index <= to
93
+ }.map { |k, v|
94
+ get_data_instance(k)
95
+ }
96
+ end
97
+
98
+ def get_account(db, id)
99
+ db.execute("select * from compta_accounts where id=#{id}").first[4]
100
+ end
101
+
102
+ def check_against_db(file)
103
+ # First build
104
+ # in_db - content of 'file' in .to_s format
105
+ # in_local - content available locally in .to_s format
106
+ in_db, diff, in_local = [], [], []
107
+
108
+ dputs(3) { 'Searching all movements' }
109
+ @check_state = 'Collect local'
110
+ @check_progress = 0.0
111
+ in_local = Movements.search_all_.reject { |m| m.value.to_f.round(3) == 0.0 }
112
+ progress_step = 1.0 / (in_local.size + 1)
113
+ dputs(3) { "Movements total: #{in_local.size}" }
114
+
115
+ @check_state = 'Collect local'
116
+ in_local = in_local.collect { |a|
117
+ @check_progress += progress_step
118
+ a.to_s
119
+ }
120
+
121
+ dputs(3) { 'Going to check all movements' }
122
+ @check_state = 'Collect file-DB'
123
+ @check_progress = 0.0
124
+ SQLite3::Database.new(file) do |db|
125
+ db.execute('select id, desc, global_id, value, date, account_src_id, account_dst_id '+
126
+ 'from compta_movements').each do |row|
127
+ @check_progress += progress_step
128
+ #dputs(3) { "Looking at #{row}" }
129
+
130
+ id_, desc_, gid_, value_, date_, src_, dst_ = row
131
+ if value_.to_f.round(3) != 0.0
132
+ in_db.push "#{desc_}\r#{gid_}\t" +
133
+ "#{sprintf('%.3f', value_.to_f.round(3))}\t#{date_.to_s}\t"+
134
+ "#{get_account(db, src_)}\t#{get_account(db, dst_)}"
135
+ end
136
+ end
137
+ end
138
+
139
+ # Now compare what is available only in db and what is available only locally
140
+ dputs(3) { 'Verifying movements on one side only' }
141
+ @check_state = 'On one side'
142
+ @check_progress = 0.0
143
+ in_db.delete_if { |a|
144
+ @check_progress += progress_step
145
+ in_local.delete(a)
146
+ }
147
+
148
+ # And search for accounts with same global-id but different content
149
+ dputs(3) { 'Verifying mixed-up movements' }
150
+ (in_db + in_local).sort_by { |a| a.match(/\r(.*?)\t/)[1] }
151
+ @check_state = 'Mixed-up'
152
+ @check_progress = 0.0
153
+ progress_step = 1.0 / (in_db.size + 1)
154
+ in_db.delete_if { |a|
155
+ @check_progress += progress_step
156
+ gid = a.match(/\r(.*?)\t/)[1]
157
+ if c = in_local.find { |b| b =~ /\r#{gid}\t/ }
158
+ diff.push [a, c]
159
+ in_local.delete c
160
+ end
161
+ }
162
+
163
+ @check_state = 'Done'
164
+ [in_db, diff, in_local]
165
+ end
166
+
167
+ end
168
+
169
+
170
+ class Movement < Entity
171
+
172
+ def init_instance
173
+ end
174
+
175
+ def data_set(f, v)
176
+ if f != :_rev_index
177
+ dputs(3){"Updating index for field #{f.inspect}"}
178
+ new_index
179
+ end
180
+ super(f, v)
181
+ end
182
+
183
+ def new_index
184
+ u_l = Users.match_by_name('local')
185
+ self.rev_index = u_l.movement_index.to_i
186
+ u_l.movement_index = self.rev_index + 1
187
+ dputs(3) { "index is #{self.rev_index} and date is --#{self.date}--" }
188
+ dputs(3) { "User('local').rev_index is: " + Users.match_by_name('local').movement_index.to_s }
189
+ end
190
+
191
+ def get_index
192
+ return self.rev_index
193
+ end
194
+
195
+ def is_in_account(a)
196
+ return (a == account_src or a == account_dst)
197
+ end
198
+
199
+ def value=(v)
200
+ if account_src and account_dst
201
+ dputs(3) { 'value=' + v.to_s + ':' + account_src.total.to_s }
202
+ diff = value.to_f - v.to_f
203
+ account_src.total = account_src.total.to_f + (diff * account_src.multiplier)
204
+ account_dst.total = account_dst.total.to_f - (diff * account_dst.multiplier)
205
+ end
206
+ data_set(:_value, v)
207
+ end
208
+
209
+ def get_value(account)
210
+ account_side = (account_src == account ? -1 : 1)
211
+ dputs(5) { "account_src #{account_src.inspect} == account #{account.inspect}" }
212
+ dputs(5) { "Account_side = #{account_side}" }
213
+ value.to_f * account.multiplier.to_f * account_side
214
+ end
215
+
216
+ def get_other_account(account)
217
+ account_src == account ? account_dst : account_src
218
+ end
219
+
220
+ def move_from_to(from, to)
221
+ v = self.value
222
+ self.value = 0
223
+ if account_src_id == from
224
+ self.account_src_id = to
225
+ end
226
+ if account_dst_id == from
227
+ self.account_dst_id = to
228
+ end
229
+ self.value = v
230
+ end
231
+
232
+ def set(desc, date, value, source, dest)
233
+ dputs(3) { 'self.value ' + self.value.to_s + ' - ' + value.to_s }
234
+ self.value = 0
235
+ self.account_src_id, self.account_dst_id = source, dest
236
+ if false
237
+ # Do some date-magic, so that we can give either the day, day and month or
238
+ # a complete date. The rest is filled up with todays date.
239
+ date = date.split('/')
240
+ da = Date.today
241
+ d = [da.day, da.month, da.year]
242
+ date += d.last(3 - date.size)
243
+ if date[2].to_s.size > 2
244
+ self.date = Date.strptime(date.join('/'), '%d/%m/%Y')
245
+ else
246
+ self.date = Date.strptime(date.join('/'), '%d/%m/%y')
247
+ end
248
+ else
249
+ self.date = Date.from_s(date.to_s)
250
+ end
251
+ self.desc, self.value = desc, value
252
+ dputs(DEBUG_SLOW) { 'Getting new index' }
253
+ self.new_index
254
+ dputs(DEBUG_SLOW) { 'Date ' + self.date.to_s }
255
+ end
256
+
257
+ def to_s
258
+ dputs(5) { "I am: #{to_hash.inspect} - my id is: #{global_id}" }
259
+ "#{desc}\r#{global_id}\t" +
260
+ "#{sprintf('%.3f', value.to_f.round(3))}\t#{date.to_s}\t" +
261
+ account_src.global_id.to_s + "\t" +
262
+ account_dst.global_id.to_s
263
+ end
264
+
265
+ def to_json
266
+ ActiveSupport::JSON.encode(:str => to_s)
267
+ end
268
+
269
+ # Copying over data from old AfriCompta
270
+ def account_src
271
+ account_src_id
272
+ end
273
+
274
+ def account_dst
275
+ account_dst_id
276
+ end
277
+
278
+ def delete
279
+ dputs(DEBUG_SLOW) { "Deleting movement #{desc}" }
280
+ src, dst = account_src, account_dst
281
+ dputs(3) { "totals before: #{src.get_path}=#{src.total}, " +
282
+ "#{dst.get_path}=#{dst.total}" }
283
+ self.value = 0
284
+ dputs(3) { "totals after: #{src.get_path}=#{src.total}, " +
285
+ "#{dst.get_path}=#{dst.total}" }
286
+ super
287
+ end
288
+
289
+ def value_form
290
+ Account.total_form(value)
291
+ end
292
+ end
@@ -0,0 +1,27 @@
1
+ class Remotes < Entities
2
+
3
+ def create( d )
4
+ r = super( d )
5
+ d.has_key?( :account_index ) || r.account_index = 0
6
+ d.has_key?( :movement_index ) || r.movement_index = 0
7
+ r
8
+ end
9
+
10
+ def setup_data
11
+ value_str :url
12
+ value_str :name
13
+ value_str :pass
14
+ value_int :account_index
15
+ value_int :movement_index
16
+ end
17
+ end
18
+
19
+ class Remote < Entity
20
+ def update_movement_index
21
+ self.movement_index = Users.match_by_name('local').movement_index - 1
22
+ end
23
+
24
+ def update_account_index
25
+ self.account_index = Users.match_by_name('local').account_index - 1
26
+ end
27
+ end
@@ -0,0 +1,55 @@
1
+ class Users < Entities
2
+
3
+ def setup_data
4
+ @default_type = :SQLiteAC
5
+ @data_field_id = :id
6
+
7
+ value_str :name
8
+ value_str :full
9
+ value_str :pass
10
+ #value_array :accounts
11
+ # The last account_index that got transmitted
12
+ value_int :account_index
13
+ # The last movement_index that got transmitted
14
+ value_int :movement_index
15
+ end
16
+
17
+ def load
18
+ super
19
+ if Users.search_by_name('local').count == 0
20
+ user = Users.create('local', Digest::MD5.hexdigest((rand 2**128).to_s).to_s,
21
+ rand(2 ** 128).to_s)
22
+ dputs(1) { "Created local user #{user}" }
23
+ end
24
+ end
25
+
26
+ def migration_1(u)
27
+ u.account_index ||= 0
28
+ u.movement_index ||= 0
29
+ end
30
+
31
+ def create(name, full = nil, pass = nil)
32
+ if not full or not pass
33
+ dputs(2) { "Creating with hash: #{name.inspect}" }
34
+ name, full, pass = name[:name], name[:full], name[:pass]
35
+ end
36
+ new_user = super(:name => name, :full => full, :pass => pass)
37
+ new_user.account_index, new_user.movement_index = 0, 0
38
+ new_user
39
+ end
40
+ end
41
+
42
+ class User < Entity
43
+ def update_movement_index
44
+ self.movement_index = Users.match_by_name('local').movement_index - 1
45
+ end
46
+
47
+ def update_account_index
48
+ self.account_index = Users.match_by_name('local').account_index - 1
49
+ end
50
+
51
+ def update_all
52
+ update_movement_index
53
+ update_account_index
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+
2
+ class EditMovements < View
3
+ def layout
4
+ gui_vbox do
5
+ show_str :movement
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+
2
+ class EditTabs < View
3
+ def layout
4
+ gui_vbox do
5
+ show_str :edit
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ class ReportAnnual < View
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class ReportTabs < View
2
+
3
+ end
data/lib/africompta.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler/setup'
2
+ require 'africompta/africompta'
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: africompta
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.9.8
5
+ platform: ruby
6
+ authors:
7
+ - Linus Gasser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: qooxview
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: With this module you can have a simple accounting-system
28
+ email: ineiti@linusetviviane.ch
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - ".gitignore"
34
+ - Gemfile
35
+ - Gemfile.lock
36
+ - TODO
37
+ - Test/ac_account.rb
38
+ - Test/ac_africompta.rb
39
+ - Test/ac_big.rb
40
+ - Test/ac_movement.rb
41
+ - Test/ac_sqlite.rb
42
+ - Test/config_test.yaml
43
+ - Test/db.testGestion
44
+ - Test/test.rb
45
+ - VERSION
46
+ - africompta.gemspec
47
+ - lib/africompta.rb
48
+ - lib/africompta/acaccess.rb
49
+ - lib/africompta/acqooxview.rb
50
+ - lib/africompta/africompta.rb
51
+ - lib/africompta/entities/account.rb
52
+ - lib/africompta/entities/acschemas.rb
53
+ - lib/africompta/entities/movement.rb
54
+ - lib/africompta/entities/remote.rb
55
+ - lib/africompta/entities/users.rb
56
+ - lib/africompta/views/edit/movement.rb
57
+ - lib/africompta/views/edit/tabs.rb
58
+ - lib/africompta/views/report/annual.rb
59
+ - lib/africompta/views/report/tabs.rb
60
+ homepage: https://github.com/ineiti/AfriCompta
61
+ licenses:
62
+ - GPLv3
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.2.2
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Africompta-module for QooxView
84
+ test_files: []