event_sourced_accounting 0.2.2 → 0.2.3

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
  SHA1:
3
- metadata.gz: 725485c3fb1eb0802b7e7f3553a0fdb598f0c927
4
- data.tar.gz: 9a5c5aef5200ebd25e0a1aadc0e791d213bac61a
3
+ metadata.gz: 757034522657c82880626fda4bb8222b7e9702f3
4
+ data.tar.gz: b7fdfc9e21ec74f08a59040ab4e18b3eced0e006
5
5
  SHA512:
6
- metadata.gz: b7229fe63379704b0388f1a97971a630c24f0bd2faa28fa9b89d1aca1a3887c92a9d76068cd1aa8ee0759c0e25d0c24f0a6351d82619d41593a40539bd63795b
7
- data.tar.gz: 5c177694686252945b7823a5163e7f7e6023827118e2797f82918affcec077ae5aefad2710349239c0e00c94d172c4900a53fe3a35a12ad4d0fd7384ef1c751f
6
+ metadata.gz: ce61668ed87fa606d807ed3e0864fc16d1bff53dd86632a9089a4c251f86a26078cfe29a517aa22a9d29c1b33ec60b9e18d206cbd3e27d94d88dd0b622dc358a
7
+ data.tar.gz: 9b4a9e77495d407138511ce337132ad16e1c61742f7b6c82d5fd0d9c7e972547534e54ebd756d4cceb965a0a59f32503efb7186db1bce5609521540da320cfde
data/README.markdown CHANGED
@@ -14,9 +14,6 @@ This plugin began life as a fork of the [Plutus](https://github.com/mbulat/plutu
14
14
  many added features and refactored compontents. As the aims of the ESA plug-in have completely
15
15
  changed compared to the original project, it warrants a release under its own name.
16
16
 
17
- The API is not yet declared frozen and may change, as some refactoring is still due.
18
- The documentation and test coverage is expected to be completed within April-May 2014.
19
-
20
17
 
21
18
  Installation
22
19
  ============
@@ -35,7 +35,7 @@ module ESA
35
35
 
36
36
  before_validation :update_normal_balance
37
37
  validates_presence_of :type, :name, :chart, :normal_balance
38
- validates_uniqueness_of :code, :scope => :chart_id
38
+ validates_uniqueness_of :code, :scope => :chart_id, :allow_nil => true
39
39
  validates_uniqueness_of :name, :scope => :chart_id
40
40
 
41
41
  # The balance of the account.
@@ -108,7 +108,7 @@ module ESA
108
108
  end
109
109
 
110
110
  def update!(options = {})
111
- self.freshness = Time.zone.now
111
+ self.freshness = self.next_freshness_timestamp
112
112
 
113
113
  ESA.configuration.context_checkers.each do |checker|
114
114
  if checker.respond_to? :check
@@ -121,10 +121,18 @@ module ESA
121
121
  end
122
122
 
123
123
  def update_freshness_timestamp!
124
- self.freshness = Time.zone.now
124
+ self.freshness = self.next_freshness_timestamp
125
125
  self.save if self.can_be_persisted?
126
126
  end
127
127
 
128
+ def next_freshness_timestamp
129
+ if self.parent.present?
130
+ [self.freshness, self.parent.try(:freshness)].compact.max
131
+ else
132
+ Time.zone.now
133
+ end
134
+ end
135
+
128
136
  def subcontext_namespaces
129
137
  self.subcontexts.pluck(:namespace).compact.uniq
130
138
  end
@@ -225,7 +233,7 @@ module ESA
225
233
 
226
234
  def parents_and_self
227
235
  contexts = [self]
228
- while contexts.last.parent_id.present? and
236
+ while contexts.last.parent_id.present? and
229
237
  not contexts.last.parent_id.in? contexts.map(&:id) and
230
238
  contexts.count < 16 do
231
239
  # found a valid parent
@@ -215,8 +215,8 @@ module ESA
215
215
 
216
216
  def find_account(type, name)
217
217
  if self.chart.present? and Account.valid_type?(type)
218
- self.chart.accounts.
219
- where(:type => Account.namespaced_type(type), :name => name).
218
+ Account.namespaced_type(type).constantize.
219
+ where(:chart_id => self.chart, :name => name).
220
220
  first_or_create
221
221
  end
222
222
  end
@@ -0,0 +1,11 @@
1
+ module ESA
2
+ # Records the last known state of the given Accountable object
3
+ #
4
+ # @author Lenno Nagel
5
+ class State < ActiveRecord::Base
6
+ attr_accessible :accountable, :processed_at, :unprocessed
7
+ attr_readonly :accountable
8
+
9
+ belongs_to :accountable, :polymorphic => true
10
+ end
11
+ end
@@ -4,10 +4,25 @@ module ESA
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
+ has_one :esa_state, :as => :accountable, :class_name => ESA::State, dependent: :destroy
7
8
  has_many :esa_events, :as => :accountable, :class_name => ESA::Event.extension_name(self), :extend => ESA::Associations::EventsExtension
8
9
  has_many :esa_flags, :as => :accountable, :class_name => ESA::Flag.extension_name(self), :extend => ESA::Associations::FlagsExtension
9
10
  has_many :esa_transactions, :as => :accountable, :class_name => ESA::Transaction.extension_name(self), :extend => ESA::Associations::TransactionsExtension
10
11
 
12
+ scope :esa_processed_at, lambda { |timespec|
13
+ joins("INNER JOIN `esa_states` ON `esa_states`.`accountable_id` = `#{table_name}`.`#{primary_key}` AND `esa_states`.`accountable_type` = '#{self}'").
14
+ where(esa_states: {processed_at: timespec}).
15
+ readonly(false)
16
+ }
17
+
18
+ scope :esa_unprocessed, lambda {
19
+ joins("LEFT JOIN `esa_states` ON `esa_states`.`accountable_id` = `#{table_name}`.`#{primary_key}` AND `esa_states`.`accountable_type` = '#{self}'").
20
+ where("`esa_states`.`id` IS NULL").
21
+ readonly(false)
22
+ }
23
+
24
+
25
+
11
26
  before_destroy :destroy_accountable
12
27
 
13
28
  def esa_ruleset
@@ -7,6 +7,16 @@ module ESA
7
7
  end
8
8
 
9
9
  def self.process_accountable(accountable)
10
+ processed = create_and_process_events(accountable)
11
+
12
+ state = ESA::State.where(accountable_id: accountable.id, accountable_type: accountable.class).first_or_create
13
+ state.processed_at = Time.now
14
+ state.unprocessed = processed ? 0 : accountable.esa_events.where(processed: false).count
15
+
16
+ state.save
17
+ end
18
+
19
+ def self.create_and_process_events(accountable)
10
20
  events_created = create_events(accountable)
11
21
 
12
22
  if events_created
@@ -17,6 +27,8 @@ module ESA
17
27
  # do not process later events if one fails
18
28
  return false if not event.processed
19
29
  end
30
+
31
+ true
20
32
  else
21
33
  false
22
34
  end
@@ -35,8 +35,8 @@ module ESA
35
35
  'account' => ESA::ContextProviders::AccountContextProvider,
36
36
  'accountable' => ESA::ContextProviders::AccountableContextProvider,
37
37
  'accountable_type' => ESA::ContextProviders::AccountableTypeContextProvider,
38
- 'month' => [ESA::ContextProviders::DateContextProvider, {period: :month}],
39
- 'date' => [ESA::ContextProviders::DateContextProvider, {period: :date}],
38
+ 'month' => [ESA::ContextProviders::DateContextProvider, {all: true, period: :month}],
39
+ 'date' => [ESA::ContextProviders::DateContextProvider, {all: true, period: :date}],
40
40
  }
41
41
 
42
42
  @context_tree = {
@@ -10,7 +10,11 @@ module ESA
10
10
  end
11
11
 
12
12
  def self.contained_ids(context, options = {})
13
- context.amounts.uniq.pluck(:account_id)
13
+ if options[:all].present? and options[:all] == true
14
+ context.accounts.pluck(:id)
15
+ else
16
+ context.amounts.uniq.pluck(:account_id)
17
+ end
14
18
  end
15
19
 
16
20
  def self.instantiate(parent, namespace, id, options = {})
@@ -10,7 +10,13 @@ module ESA
10
10
  end
11
11
 
12
12
  def self.contained_ids(context, options = {})
13
- dates = context.transactions.uniq.pluck("date(esa_transactions.time)").sort
13
+ if options[:all].present? and options[:all] == true and
14
+ context.effective_start_date.present? and
15
+ context.effective_end_date.present?
16
+ dates = context.effective_start_date..context.effective_end_date
17
+ else
18
+ dates = context.transactions.uniq.pluck("date(esa_transactions.time)").sort
19
+ end
14
20
 
15
21
  if options[:period].present? and options[:period] == :month
16
22
  dates.group_by{|d| [d.year, d.month]}.keys.
data/lib/esa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ESA
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
data/lib/esa.rb CHANGED
@@ -32,6 +32,7 @@ require 'esa/traits/accountable'
32
32
  require 'esa/traits/extendable'
33
33
  require 'esa/traits/or_scope'
34
34
  require 'esa/traits/union_scope'
35
+ require 'esa/state'
35
36
  require 'esa/transaction'
36
37
 
37
38
  require 'esa/blocking_processor'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event_sourced_accounting
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lenno Nagel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-02 00:00:00.000000000 Z
11
+ date: 2014-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -219,6 +219,7 @@ files:
219
219
  - app/models/esa/event.rb
220
220
  - app/models/esa/flag.rb
221
221
  - app/models/esa/ruleset.rb
222
+ - app/models/esa/state.rb
222
223
  - app/models/esa/traits/accountable.rb
223
224
  - app/models/esa/traits/extendable.rb
224
225
  - app/models/esa/traits/or_scope.rb