event_sourced_accounting 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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