mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-17 06:52:27 +01:00
debug footprints
This commit is contained in:
parent
52ac637e27
commit
7bf06ff23e
@ -1,8 +1,10 @@
|
|||||||
# Changelog Fab-manager
|
# Changelog Fab-manager
|
||||||
|
|
||||||
- Display an asterisk on the phone input field, in the admin creation form, if the phone is configured as required
|
- Display an asterisk on the phone input field, in the admin creation form, if the phone is configured as required
|
||||||
|
- Keep the history of footprints data for verification purposes
|
||||||
- Fix a bug: unable to export reservations
|
- Fix a bug: unable to export reservations
|
||||||
- Fix a bug: unable to receive mails in development
|
- Fix a bug: unable to receive mails in development
|
||||||
|
- [TODO DEPLOY] `rails fablab:maintenance:save_footprint_data`
|
||||||
|
|
||||||
## v4.5.3 2020 July 21
|
## v4.5.3 2020 July 21
|
||||||
|
|
||||||
|
2
app/models/footprint_debug.rb
Normal file
2
app/models/footprint_debug.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class FootprintDebug < ApplicationRecord
|
||||||
|
end
|
@ -12,12 +12,21 @@ class HistoryValue < ApplicationRecord
|
|||||||
def chain_record
|
def chain_record
|
||||||
self.footprint = compute_footprint
|
self.footprint = compute_footprint
|
||||||
save!
|
save!
|
||||||
|
FootprintDebug.create!(
|
||||||
|
footprint: footprint,
|
||||||
|
data: FootprintService.footprint_data(HistoryValue, self, 'created_at'),
|
||||||
|
klass: HistoryValue.name
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_footprint
|
def check_footprint
|
||||||
footprint == compute_footprint
|
footprint == compute_footprint
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def debug_footprint
|
||||||
|
FootprintService.debug_footprint(HistoryValue, self)
|
||||||
|
end
|
||||||
|
|
||||||
def user
|
def user
|
||||||
invoicing_profile.user
|
invoicing_profile.user
|
||||||
end
|
end
|
||||||
|
@ -174,12 +174,21 @@ class Invoice < ApplicationRecord
|
|||||||
def chain_record
|
def chain_record
|
||||||
self.footprint = compute_footprint
|
self.footprint = compute_footprint
|
||||||
save!
|
save!
|
||||||
|
FootprintDebug.create!(
|
||||||
|
footprint: footprint,
|
||||||
|
data: FootprintService.footprint_data(Invoice, self),
|
||||||
|
klass: Invoice.name
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_footprint
|
def check_footprint
|
||||||
invoice_items.map(&:check_footprint).all? && footprint == compute_footprint
|
invoice_items.map(&:check_footprint).all? && footprint == compute_footprint
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def debug_footprint
|
||||||
|
FootprintService.debug_footprint(Invoice, self)
|
||||||
|
end
|
||||||
|
|
||||||
def set_wallet_transaction(amount, transaction_id)
|
def set_wallet_transaction(amount, transaction_id)
|
||||||
raise InvalidFootprintError unless check_footprint
|
raise InvalidFootprintError unless check_footprint
|
||||||
|
|
||||||
|
@ -15,12 +15,21 @@ class InvoiceItem < ApplicationRecord
|
|||||||
def chain_record
|
def chain_record
|
||||||
self.footprint = compute_footprint
|
self.footprint = compute_footprint
|
||||||
save!
|
save!
|
||||||
|
FootprintDebug.create!(
|
||||||
|
footprint: footprint,
|
||||||
|
data: FootprintService.footprint_data(InvoiceItem, self),
|
||||||
|
klass: InvoiceItem.name
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_footprint
|
def check_footprint
|
||||||
footprint == compute_footprint
|
footprint == compute_footprint
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def debug_footprint
|
||||||
|
FootprintService.debug_footprint(InvoiceItem, self)
|
||||||
|
end
|
||||||
|
|
||||||
def amount_after_coupon
|
def amount_after_coupon
|
||||||
# deduct coupon discount
|
# deduct coupon discount
|
||||||
coupon_service = CouponService.new
|
coupon_service = CouponService.new
|
||||||
|
@ -3,19 +3,47 @@
|
|||||||
# Provides helper methods to compute footprints
|
# Provides helper methods to compute footprints
|
||||||
class FootprintService
|
class FootprintService
|
||||||
# Compute the footprint
|
# Compute the footprint
|
||||||
# @param class_name Invoice|InvoiceItem|HistoryValue
|
# @param klass Invoice|InvoiceItem|HistoryValue
|
||||||
# @param item an instance of the provided class
|
# @param item an instance of the provided class
|
||||||
# @param sort the items in database by the provided criterion, to find the previous one
|
# @param sort the items in database by the provided criterion, to find the previous one
|
||||||
def self.compute_footprint(klass, item, sort_on = 'id')
|
def self.compute_footprint(klass, item, sort_on = 'id')
|
||||||
|
Checksum.text(FootprintService.footprint_data(klass, item, sort_on))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return the original data string used to compute the footprint
|
||||||
|
# @param klass Invoice|InvoiceItem|HistoryValue
|
||||||
|
# @param item an instance of the provided class
|
||||||
|
# @param sort the items in database by the provided criterion, to find the previous one
|
||||||
|
def self.footprint_data(klass, item, sort_on = 'id')
|
||||||
raise TypeError unless item.is_a? klass
|
raise TypeError unless item.is_a? klass
|
||||||
|
|
||||||
previous = klass.where("#{sort_on} < ?", item[sort_on])
|
previous = klass.where("#{sort_on} < ?", item[sort_on])
|
||||||
.order("#{sort_on} DESC")
|
.order("#{sort_on} DESC")
|
||||||
.limit(1)
|
.limit(1)
|
||||||
|
|
||||||
columns = klass.columns.map(&:name)
|
columns = FootprintService.footprint_columns(klass)
|
||||||
.delete_if { |c| %w[footprint updated_at].include? c }
|
|
||||||
|
|
||||||
Checksum.text("#{columns.map { |c| item[c] }.join}#{previous.first ? previous.first.footprint : ''}")
|
"#{columns.map { |c| item[c] }.join}#{previous.first ? previous.first.footprint : ''}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return an ordered array of the columns used in the footprint computation
|
||||||
|
# @param klass Invoice|InvoiceItem|HistoryValue
|
||||||
|
def self.footprint_columns(klass)
|
||||||
|
klass.columns.map(&:name).delete_if { |c| %w[footprint updated_at].include? c }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Logs a debugging message to help finding why a footprint is invalid
|
||||||
|
# @param klass Invoice|InvoiceItem|HistoryValue
|
||||||
|
# @param item an instance of the provided class
|
||||||
|
def self.debug_footprint(klass, item)
|
||||||
|
columns = FootprintService.footprint_columns(klass)
|
||||||
|
current = FootprintService.footprint_data(klass, item)
|
||||||
|
saved = FootprintDebug.find_by(footprint: item.footprint, klass: klass)
|
||||||
|
puts "Debug footprint for Invoice [ id: #{item.id} ]"
|
||||||
|
puts '-----------------------------------------'
|
||||||
|
puts "columns: [ #{columns.join(', ')} ]"
|
||||||
|
puts "current footprint: #{current}"
|
||||||
|
puts " saved footprint: #{saved&.data}"
|
||||||
|
puts '-----------------------------------------'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
15
db/migrate/20200721162939_create_footprint_debugs.rb
Normal file
15
db/migrate/20200721162939_create_footprint_debugs.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# This table saves the original data used to create footprints, this allows
|
||||||
|
# to debug invalid footprints
|
||||||
|
class CreateFootprintDebugs < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :footprint_debugs do |t|
|
||||||
|
t.string :footprint
|
||||||
|
t.string :data
|
||||||
|
t.string :klass
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -763,6 +763,39 @@ CREATE SEQUENCE public.exports_id_seq
|
|||||||
ALTER SEQUENCE public.exports_id_seq OWNED BY public.exports.id;
|
ALTER SEQUENCE public.exports_id_seq OWNED BY public.exports.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: footprint_debugs; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.footprint_debugs (
|
||||||
|
id bigint NOT NULL,
|
||||||
|
footprint character varying,
|
||||||
|
data character varying,
|
||||||
|
klass character varying,
|
||||||
|
created_at timestamp without time zone NOT NULL,
|
||||||
|
updated_at timestamp without time zone NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: footprint_debugs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.footprint_debugs_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: footprint_debugs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.footprint_debugs_id_seq OWNED BY public.footprint_debugs.id;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: friendly_id_slugs; Type: TABLE; Schema: public; Owner: -
|
-- Name: friendly_id_slugs; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -3020,6 +3053,13 @@ ALTER TABLE ONLY public.events_event_themes ALTER COLUMN id SET DEFAULT nextval(
|
|||||||
ALTER TABLE ONLY public.exports ALTER COLUMN id SET DEFAULT nextval('public.exports_id_seq'::regclass);
|
ALTER TABLE ONLY public.exports ALTER COLUMN id SET DEFAULT nextval('public.exports_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: footprint_debugs id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.footprint_debugs ALTER COLUMN id SET DEFAULT nextval('public.footprint_debugs_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: friendly_id_slugs id; Type: DEFAULT; Schema: public; Owner: -
|
-- Name: friendly_id_slugs id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -3607,6 +3647,14 @@ ALTER TABLE ONLY public.exports
|
|||||||
ADD CONSTRAINT exports_pkey PRIMARY KEY (id);
|
ADD CONSTRAINT exports_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: footprint_debugs footprint_debugs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.footprint_debugs
|
||||||
|
ADD CONSTRAINT footprint_debugs_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: friendly_id_slugs friendly_id_slugs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: friendly_id_slugs friendly_id_slugs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -5598,6 +5646,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||||||
('20200622135401'),
|
('20200622135401'),
|
||||||
('20200623134900'),
|
('20200623134900'),
|
||||||
('20200623141305'),
|
('20200623141305'),
|
||||||
('20200629123011');
|
('20200629123011'),
|
||||||
|
('20200721162939');
|
||||||
|
|
||||||
|
|
||||||
|
29
lib/tasks/db.rake
Normal file
29
lib/tasks/db.rake
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# frozen_string_literal: false
|
||||||
|
|
||||||
|
namespace :db do
|
||||||
|
desc 'Convert development DB to Rails test fixtures'
|
||||||
|
task to_fixtures: :environment do
|
||||||
|
TABLES_TO_SKIP = %w[ar_internal_metadata delayed_jobs schema_info schema_migrations].freeze
|
||||||
|
|
||||||
|
begin
|
||||||
|
ActiveRecord::Base.establish_connection
|
||||||
|
ActiveRecord::Base.connection.tables.each do |table_name|
|
||||||
|
next if TABLES_TO_SKIP.include?(table_name)
|
||||||
|
|
||||||
|
conter = '000'
|
||||||
|
file_path = "#{Rails.root}/test/fixtures/#{table_name}.yml"
|
||||||
|
File.open(file_path, 'w') do |file|
|
||||||
|
rows = ActiveRecord::Base.connection.select_all("SELECT * FROM #{table_name}")
|
||||||
|
data = rows.each_with_object({}) do |record, hash|
|
||||||
|
suffix = record['id'].blank? ? conter.succ! : record['id']
|
||||||
|
hash["#{table_name.singularize}_#{suffix}"] = record
|
||||||
|
end
|
||||||
|
puts "Writing table '#{table_name}' to '#{file_path}'"
|
||||||
|
file.write(data.to_yaml)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Base.connection&.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -91,5 +91,18 @@ namespace :fablab do
|
|||||||
Sidekiq::Queue.new('default').clear
|
Sidekiq::Queue.new('default').clear
|
||||||
Sidekiq::DeadSet.new.clear
|
Sidekiq::DeadSet.new.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc 'save the footprint original data'
|
||||||
|
task save_footprint_data: :environment do
|
||||||
|
[Invoice, InvoiceItem, HistoryValue].each do |klass|
|
||||||
|
klass.all.each do |item|
|
||||||
|
FootprintDebug.create!(
|
||||||
|
footprint: item.footprint,
|
||||||
|
data: FootprintService.footprint_data(klass, item, klass == 'HistoryValue' ? 'created_at' : 'id'),
|
||||||
|
klass: klass
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
645
test/fixtures/footprint_debugs.yml
vendored
Normal file
645
test/fixtures/footprint_debugs.yml
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user