diff --git a/app/models/admin_log.rb b/app/models/admin_log.rb index a6830a7..ee98670 100644 --- a/app/models/admin_log.rb +++ b/app/models/admin_log.rb @@ -3,17 +3,13 @@ class AdminLog < ActiveRecord::Base validates :table_name, :old_value, :new_value, :admin_id, :presence=> true + # This static method returns a function suitable fo use as an around_filter + # which will log actions. + # 'field' is the name of a property whose value should be logged on change. def self.log field return Proc.new {|controller, action| - user = controller.me - - if !user - puts "UNKNOWN ADMIN USER! HALP!!!!!!" - crash - end - obj = controller.send(field) before = "null" @@ -33,11 +29,8 @@ def self.log field end table = obj.class.name - - puts "TRALALALALALA", user, before, after if before != after - puts "WEEE SAVELISAVE SAVE SAVE SAVE" l = AdminLog.new({:admin => user, :old_value => before, :new_value => after, :table_name => table}) l.save puts l.errors @@ -45,8 +38,21 @@ def self.log field } end + # Return a list of hashes. every hash has three items, :field, which is a field name, + # :before, which is the old value, and :after is the new value. This list includes only + # the changed fields. def changes return Log.diff self.old_value, self.new_value end + # Return a list of hashes. every hash has three items, :field, which is a field name, + # :before, which is the old value, and :after is the new value + def data + before = Log.handle_json self.old_value + after = Log.handle_json self.new_value + fields = before.keys | after.keys + return fields.map {|key| { :field => key, :before => before[key], :after => after[key] } } + end + + end diff --git a/app/models/log.rb b/app/models/log.rb index 814189c..8d809d4 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -5,17 +5,21 @@ class Log < ActiveRecord::Base validates :table_name, :old_value, :new_value, :user_id, :company_id, :presence=> true + # Convert the specified model isntance to JSON. If the object has a log_include property, + # include the foreign keys returned by that property def self.my_json obj inc = obj.log_include if obj.respond_to?(:log_include) else [] return obj.to_json :include => inc end - + + # This static method returns a function suitable fo use as an around_filter + # which will log actions. + # 'field' is the name of a property whose value should be logged on change. def self.log field return Proc.new {|controller, action| user = controller.me company = user.current_company -# puts "AFSDDDDDDD", controller, field obj = controller.send(field) before = "null" @@ -43,13 +47,16 @@ def self.log field } end + # Return a list of hashes. every hash has three items, :field, which is a field name, + # :before, which is the old value, and :after is the new value. This list includes only + # the changed fields. def changes - puts "AAAAAAAA", self[0] return Log.diff self.old_value, self.new_value end - def self.diff old_value, new_value - + # Parse a JSON string and flatten dicts and lists into a single hash + def self.handle_json text + def self.my_flatten_internal source, destination, prefix source.each { |key, value| if key != "updated_at" @@ -58,9 +65,7 @@ def self.my_flatten_internal source, destination, prefix else if value.class == Array valhash = Hash[value.map {|it| ["element" + it["id"].to_s, it] }] - puts "WEEE", value, "=>", valhash, "YAY" my_flatten_internal valhash, destination, prefix + key + " " - # puts destination else destination[prefix+key] = value end @@ -74,20 +79,19 @@ def self.my_flatten source return my_flatten_internal source, {}, "" end - before = ActiveSupport::JSON.decode(old_value) - after = ActiveSupport::JSON.decode(new_value) - - if before - before = my_flatten before.values.first - else - before = {} + data = ActiveSupport::JSON.decode text + if data + return my_flatten data.values.first end + return {} + end + + # Helper method for the changes method. + # Refactored out of changes so that it can be used by AdminLog.changes as well. + def self.diff old_value, new_value - if after - after = my_flatten after.values.first - else - after = {} - end + before = Log.handle_json old_value + after = Log.handle_json new_value def self.my_filter k1, k2 if !k1 && !k2 @@ -101,5 +105,15 @@ def self.my_filter k1, k2 fields = fields.select {|key| my_filter(before[key], after[key])} return fields.map {|key| { :field => key, :before => before[key], :after => after[key] } } end - + + # Return a list of hashes. every hash has three items, :field, which is a field name, + # :before, which is the old value, and :after is the new value + def data + before = Log.handle_json self.old_value + after = Log.handle_json self.new_value + fields = before.keys | after.keys + return fields.map {|key| { :field => key, :before => before[key], :after => after[key] } } + end + + end diff --git a/app/models/period.rb b/app/models/period.rb index 28dce9e..356f5c2 100644 --- a/app/models/period.rb +++ b/app/models/period.rb @@ -9,10 +9,10 @@ class Period < ActiveRecord::Base cattr_reader :per_page @@per_page = 200 - STATUSES = {0 => 'New', 1 => 'Open', 2 => 'Done', 3 => 'Closed'} - STATUSE_NAMES = {'New' => 0, 'Open' => 1, 'Done' => 2, 'Closed' => 3} + STATUSES = {0 => 'New', 1 => 'Open', 2 => 'Done', 3 => 'Locked', 4 => 'Closed'} + STATUSE_NAMES = {'New' => 0, 'Open' => 1, 'Done' => 2, 'Locked' => 3, 'Closed' => 4} - # options: from_year, from_nr, to_year, to_nr, company_id + # options: from_year, from_nr, to_year, to_nr, company_id # if (from_year, to_year) are nil, it will return all periods of the company from year 1900 to year 3999 # if (to_year) is nil, it will return all periods until last period of the company until year 3999 # if (from_year) is nil, it will return all periods since first period of the company since year 1900 diff --git a/app/views/admin/admin_logs/index.html.erb b/app/views/admin/admin_logs/index.html.erb index a200845..a30be23 100644 --- a/app/views/admin/admin_logs/index.html.erb +++ b/app/views/admin/admin_logs/index.html.erb @@ -8,6 +8,7 @@ User Created at Changes + <% @admin_logs.each do |log| %> @@ -15,8 +16,9 @@ <%= log.table_name %> <%= log.admin %> <%= log.created_at %> - - + + <% end %> diff --git a/app/views/logs/index.html.erb b/app/views/logs/index.html.erb index 0d62e9d..f5860e0 100644 --- a/app/views/logs/index.html.erb +++ b/app/views/logs/index.html.erb @@ -8,6 +8,7 @@ + <% @logs.each do |log| %> @@ -15,8 +16,9 @@ -
+ + @@ -30,6 +32,24 @@ <% end %>
<%= t('logs.field') %> <%= t('logs.before') %>
+ + + + + + + + <% log.data.each do |change| %> + + + + + + <% end %> + +
+
User Created at Changes
<%= log.table_name %> <%= log.user %> <%= log.created_at %> - + + <% end %> diff --git a/app/views/periods/index.html.erb b/app/views/periods/index.html.erb index 986d822..e71c77a 100644 --- a/app/views/periods/index.html.erb +++ b/app/views/periods/index.html.erb @@ -14,6 +14,7 @@ + @@ -24,15 +25,16 @@ + <% for status in (0..period.status - 1) %> - <% end %> - <% if period.status < 3 then %> + <% end %> + <% if period.status < 4 then %> <% else %> <% end %> - <% for status in (period.status+1..3) %> + <% for status in (period.status+1..4) %> <% end %> diff --git a/config/authorization_rules.rb b/config/authorization_rules.rb index 2d2e1f2..9c9defd 100644 --- a/config/authorization_rules.rb +++ b/config/authorization_rules.rb @@ -133,6 +133,11 @@ if_attribute :period => { :status => [ Period::STATUSE_NAMES['Open'], Period::STATUSE_NAMES['Done'] ] } end + has_permission_on :journals, :to => :manage, :join_by => :and do + if_attribute :company_id => is {user.current_company.id} + if_attribute :period => { :status => [ Period::STATUSE_NAMES['Locked']] } + end + has_permission_on :bills, :to => :manage, :join_by => :and do if_attribute :company_id => is {user.current_company.id} if_attribute :period => { :status => [ Period::STATUSE_NAMES['Open'], Period::STATUSE_NAMES['Done'] ] }
+ + @@ -30,6 +32,25 @@ <% end %>
<%= t('logs.field') %> <%= t('logs.before') %>
+ + + + + + + + <% log.data.each do |change| %> + + + + + + <% end %> + + +
+
New Open DoneLocked Closed Open bills Bills
<%= period.year %> <%= period.nr %><%= link_to '->'.html_safe, elevate_status_period_path(period), :method => :post %>X<%= period.open_bills.count %>