1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00

(feat) improved chaining system

This commit is contained in:
Sylvain 2023-03-23 17:39:06 +01:00
parent 5295cc94ef
commit 71a9a87315
56 changed files with 2241 additions and 1847 deletions

View File

@ -15,7 +15,6 @@ gem 'matrix'
gem 'net-imap', require: false
gem 'net-pop', require: false
gem 'net-smtp', require: false
gem 'psych', '< 4'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'

View File

@ -316,7 +316,6 @@ GEM
ttfunk (~> 1.7)
prawn-table (0.2.2)
prawn (>= 1.3.0, < 3.0.0)
psych (3.3.4)
public_suffix (4.0.6)
puma (6.1.0)
nio4r (~> 2.0)
@ -569,7 +568,6 @@ DEPENDENCIES
pg_search
prawn
prawn-table
psych (< 4)
puma (= 6.1.0)
pundit
railroady

View File

@ -0,0 +1,37 @@
# frozen_string_literal: true
require 'integrity/checksum'
require 'json'
# ChainedElement saves data about a securly footprinted chained element (like invoices)
class ChainedElement < ApplicationRecord
belongs_to :element, polymorphic: true
belongs_to :previous, class_name: 'ChainedElement'
has_one :next, class_name: 'ChainedElement', inverse_of: :previous, dependent: :restrict_with_exception
before_create :set_content, :chain_record
validates :element_id, :element_type, presence: true
# @return [Boolean]
def corrupted?
comparable(FootprintService.chained_data(element, previous&.footprint)) != comparable(content) ||
footprint != Integrity::Checksum.text(comparable(content).to_json)
end
private
def set_content
self.content = FootprintService.chained_data(element, previous&.footprint)
end
def chain_record
self.footprint = Integrity::Checksum.text(content.to_json)
end
# @param item [Hash]
# @return [Hash]
def comparable(item)
item.sort.to_h.transform_values { |val| val.is_a?(Hash) ? val.sort.to_h : val }
end
end

View File

@ -1,33 +0,0 @@
# frozen_string_literal: true
# When a footprint is generated, the associated data is kept to allow further verifications
class FootprintDebug < ApplicationRecord
# We try to rebuild the data, column by column, from the db object
# If any datum oes not match, we print it as ERROR
def format_data(item_id)
item = klass.constantize.find(item_id)
columns = FootprintService.footprint_columns(klass.constantize)
result = []
index = 0
columns.each do |column|
col_data = item[column]
end_idx = index + col_data.to_s.length - 1
if data[index..end_idx] == col_data.to_s
# if the item data for the current column matches, save it into the results and move forward teh cursor
result.push(col_data.to_s)
index = end_idx + 1
else
# if the item data for the current column does not matches, mark it as an error, display the next chars, but do not move the cursor
datum = data[index..end_idx]
datum = data[index..index + 5] if datum&.empty?
result.push "ERROR (#{datum}...)"
end
end
# the remaining data is the previous record checksum
result.push(data[index..-1])
result
end
end

View File

@ -17,24 +17,28 @@ class Footprintable < ApplicationRecord
end
def check_footprint
footprint_children.map(&:check_footprint).all? && footprint == compute_footprint
return false unless persisted?
footprint_children.map(&:check_footprint).all? && !chained_element.corrupted?
end
# @return [ChainedElement]
def chain_record
self.footprint = compute_footprint
save!
FootprintDebug.create!(
footprint: footprint,
data: FootprintService.footprint_data(self.class, self),
klass: self.class.name
ChainedElement.create!(
element: self,
previous: previous_record&.chained_element
)
end
# @return [Footprintable,NilClass]
def previous_record
self.class.where("#{sort_on_field} < ?", self[sort_on_field])
.order("#{sort_on_field} DESC")
.limit(1)
.first
end
def debug_footprint
FootprintService.debug_footprint(self.class, self)
end
def compute_footprint
FootprintService.compute_footprint(self.class, self)
end
end

View File

@ -5,6 +5,7 @@ class HistoryValue < Footprintable
belongs_to :setting
belongs_to :invoicing_profile
has_one :chained_element, as: :element, dependent: :restrict_with_exception
delegate :user, to: :invoicing_profile
after_create :chain_record

View File

@ -14,7 +14,7 @@ class Import < ApplicationRecord
after_commit :proceed_import, on: [:create]
def results_hash
YAML.safe_load(results, [Symbol]) if results
YAML.safe_load(results, permitted_classes: [Symbol]) if results
end
private

View File

@ -13,6 +13,7 @@ class Invoice < PaymentDocument
belongs_to :wallet_transaction
belongs_to :coupon
has_one :chained_element, as: :element, dependent: :restrict_with_exception
has_one :avoir, class_name: 'Invoice', dependent: :destroy, inverse_of: :avoir
has_one :payment_schedule_item, dependent: :restrict_with_error
has_one :payment_gateway_object, as: :item, dependent: :destroy

View File

@ -7,6 +7,7 @@ class InvoiceItem < Footprintable
has_one :invoice_item, dependent: :destroy # associates invoice_items of an invoice to invoice_items of an Avoir
has_one :payment_gateway_object, as: :item, dependent: :destroy
has_one :chained_element, as: :element, dependent: :restrict_with_exception
belongs_to :object, polymorphic: true
after_create :chain_record

View File

@ -11,6 +11,7 @@ class PaymentSchedule < PaymentDocument
belongs_to :statistic_profile
belongs_to :operator_profile, class_name: 'InvoicingProfile'
has_one :chained_element, as: :element, dependent: :restrict_with_exception
has_many :payment_schedule_items, dependent: :destroy
has_many :payment_gateway_objects, as: :item, dependent: :destroy
has_many :payment_schedule_objects, dependent: :destroy

View File

@ -5,6 +5,7 @@ class PaymentScheduleItem < Footprintable
belongs_to :payment_schedule
belongs_to :invoice
has_one :payment_gateway_object, as: :item, dependent: :destroy
has_one :chained_element, as: :element, dependent: :restrict_with_exception
after_create :chain_record

View File

@ -7,6 +7,7 @@ class PaymentScheduleObject < Footprintable
belongs_to :subscription, foreign_key: 'object_id', inverse_of: :payment_schedule_object
belongs_to :statistic_profile_prepaid_pack, foreign_key: 'object_id', inverse_of: :payment_schedule_object
belongs_to :payment_schedule
has_one :chained_element, as: :element, dependent: :restrict_with_exception
after_create :chain_record
end

View File

@ -1,77 +1,62 @@
# frozen_string_literal: true
require 'integrity/checksum'
require 'json'
# Provides helper methods to compute footprints
class FootprintService
class << self
# Compute the footprint
# @param klass {Class} a class inheriting from Footprintable
# @param item {Footprintable} an instance of the provided class
def compute_footprint(klass, item)
Integrity::Checksum.text(FootprintService.footprint_data(klass, item))
end
# @param item [Footprintable]
# @param previous_footprint [String,NilClass]
# @return {Hash<Symbol->String,Integer,Hash>}
def chained_data(item, previous_footprint = nil)
columns = footprint_columns(item.class)
res = {}
columns.each do |column|
next if column.blank? || item[column].blank?
# Return the original data string used to compute the footprint
# @param klass {Class} a class inheriting from Footprintable
# @param item {Footprintable} an instance of the provided class
# @param array {Boolean} if true, the result is return on the form of an array, otherwise a concatenated string is returned
def footprint_data(klass, item, array: false)
raise TypeError unless item.is_a? klass
sort_on = item.sort_on_field
previous = klass.where("#{sort_on} < ?", item[sort_on])
.order("#{sort_on} DESC")
.limit(1)
columns = FootprintService.footprint_columns(klass)
columns = columns.map do |c|
comparable(item[c])
res[column] = comparable(item[column])
rescue ActiveModel::MissingAttributeError
nil
res[column] = nil
end
res = columns.push(previous.first ? previous.first.footprint : '')
array ? res.map(&:to_s) : res.join.to_s
res['previous'] = previous_footprint
res.sort.to_h
end
# Return an ordered array of the columns used in the footprint computation
# @param klass {Class} a class inheriting from Footprintable
# @param klass [Class] a class inheriting from Footprintable
def footprint_columns(klass)
%w[id].concat(klass.columns.map(&:name).delete_if { |c| %w[id footprint updated_at].concat(klass.columns_out_of_footprint).include? c }.sort)
%w[id].concat(klass.columns.map(&:name).delete_if do |column|
%w[id footprint updated_at].concat(klass.columns_out_of_footprint).include?(column)
end.sort)
end
# Logs a debugging message to help finding why a footprint is invalid
# @param klass {Class} a class inheriting from Footprintable
# @param item {Footprintable} an instance of the provided class
# @param klass [Class] a class inheriting from Footprintable
# @param item [Footprintable] an instance of the provided class
def debug_footprint(klass, item)
columns = FootprintService.footprint_columns(klass)
current = FootprintService.footprint_data(klass, item, array: true)
saved = FootprintDebug.find_by(footprint: item.footprint, klass: klass.name)
return saved if Rails.env.test?
current = chained_data(item, item.chained_element.previous&.footprint)
saved = item.chained_element&.content&.sort&.to_h&.transform_values { |val| val.is_a?(Hash) ? val.sort.to_h : val }
if saved.nil?
Rails.logger.debug { "Debug data not found for #{klass} [ id: #{item.id} ]" }
" #{klass} [ id: #{item.id} ] is not chained"
else
Rails.logger.debug do
"Debug footprint for #{klass} [ id: #{item.id} ]\n" \
"-----------------------------------------\ncolumns: [ #{columns.join(', ')} ]\n" \
"current: #{current}\n saved: #{saved.format_data(item.id)}\n" \
'-----------------------------------------'
end
item.footprint_children.map(&:debug_footprint)
"Debug footprint for #{klass} [ id: #{item.id} ]\n" \
"-----------------------------------------\n" \
"=== current ===\n#{JSON.pretty_generate(current)}\n\n=== saved ===\n#{JSON.pretty_generate(saved)}\n" \
"-----------------------------------------\n" +
item.footprint_children.map(&:debug_footprint).join("\n\n")
end
others = FootprintDebug.where('klass = ? AND data LIKE ? AND id != ?', klass, "#{item.id}%", saved&.id)
Rails.logger.debug { "other possible matches IDs: #{others.map(&:id)}\n-----------------------------------------" }
end
private
# Return a comparable value for jsonb fields (with keys ordered alphabetically)
def comparable(value)
return value.iso8601 if value.is_a? Time
return value unless value.is_a? Hash
value.sort.to_h
value.sort.to_h.transform_values! { |v| comparable(v) }
end
end
end

View File

@ -34,6 +34,8 @@ class FabManager::Application < Rails::Application
config.active_record.belongs_to_required_by_default = false
config.active_record.schema_format = :sql
config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.

View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
# From this migration, we save the chained elements in a separate table instead of adding footprints in their tables (like in invoices)
# This will allows more flexibility for the models
class CreateChainedElements < ActiveRecord::Migration[6.1]
def up
create_table :chained_elements do |t|
t.references :element, index: true, polymorphic: true, null: false
t.integer :previous_id
t.foreign_key :chained_elements, column: :previous_id, primary_key: :id
t.jsonb :content, null: false
t.string :footprint, null: false
t.timestamps
end
execute <<~SQL.squish
CREATE OR REPLACE RULE chained_elements_upd_protect AS ON UPDATE
TO chained_elements
WHERE (
new.content <> old.content OR
new.footprint <> old.footprint OR
new.previous_id <> old.previous_id OR
new.element_id <> old.element_id OR
new.element_type <> old.element_type)
DO INSTEAD NOTHING;
SQL
end
def down
execute <<~SQL.squish
DROP RULE IF EXISTS chained_elements_upd_protect ON chained_elements;
SQL
drop_table :chained_elements
end
end

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
# From this migration, we migrate the chaining system to the new chained_elements table
class MigrateChainingSystem < ActiveRecord::Migration[6.1]
def up
[Invoice, InvoiceItem, HistoryValue, PaymentSchedule, PaymentScheduleItem, PaymentScheduleObject].each do |klass|
order = klass == HistoryValue ? :created_at : :id
previous = nil
klass.order(order).find_each do |item|
created = ChainedElement.create!(
element: item,
previous: previous
)
previous = created
end
end
end
def down
execute("TRUNCATE TABLE #{ChainedElement.arel_table.name}")
end
end

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
# From this migration we delete the footprint_debugs table became useless
class DropFootprintDebugs < ActiveRecord::Migration[6.1]
def change
drop_table :footprint_debugs do |t|
t.string :footprint
t.string :data
t.string :klass
t.timestamps
end
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
# We remove the footprint columns became useless
class DropFootprintColumn < ActiveRecord::Migration[6.1]
def change
remove_column :invoices, :footprint, :string
remove_column :invoice_items, :footprint, :string
remove_column :history_values, :footprint, :string
remove_column :payment_schedules, :footprint, :string
remove_column :payment_schedule_items, :footprint, :string
remove_column :payment_schedule_objects, :footprint, :string
end
end

View File

@ -85,11 +85,11 @@ CREATE FUNCTION public.fill_search_vector_for_project() RETURNS trigger
select string_agg(description, ' ') as content into step_description from project_steps where project_id = new.id;
new.search_vector :=
setweight(to_tsvector('pg_catalog.french', unaccent(coalesce(new.name, ''))), 'A') ||
setweight(to_tsvector('pg_catalog.french', unaccent(coalesce(new.tags, ''))), 'B') ||
setweight(to_tsvector('pg_catalog.french', unaccent(coalesce(new.description, ''))), 'D') ||
setweight(to_tsvector('pg_catalog.french', unaccent(coalesce(step_title.title, ''))), 'C') ||
setweight(to_tsvector('pg_catalog.french', unaccent(coalesce(step_description.content, ''))), 'D');
setweight(to_tsvector('pg_catalog.norwegian', unaccent(coalesce(new.name, ''))), 'A') ||
setweight(to_tsvector('pg_catalog.norwegian', unaccent(coalesce(new.tags, ''))), 'B') ||
setweight(to_tsvector('pg_catalog.norwegian', unaccent(coalesce(new.description, ''))), 'D') ||
setweight(to_tsvector('pg_catalog.norwegian', unaccent(coalesce(step_title.title, ''))), 'C') ||
setweight(to_tsvector('pg_catalog.norwegian', unaccent(coalesce(step_description.content, ''))), 'D');
return new;
end
@ -335,8 +335,8 @@ ALTER SEQUENCE public.age_ranges_id_seq OWNED BY public.age_ranges.id;
CREATE TABLE public.ar_internal_metadata (
key character varying NOT NULL,
value character varying,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
@ -857,6 +857,41 @@ CREATE SEQUENCE public.categories_id_seq
ALTER SEQUENCE public.categories_id_seq OWNED BY public.categories.id;
--
-- Name: chained_elements; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.chained_elements (
id bigint NOT NULL,
element_type character varying NOT NULL,
element_id bigint NOT NULL,
previous_id integer,
content jsonb NOT NULL,
footprint character varying NOT NULL,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);
--
-- Name: chained_elements_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.chained_elements_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: chained_elements_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.chained_elements_id_seq OWNED BY public.chained_elements.id;
--
-- Name: components; Type: TABLE; Schema: public; Owner: -
--
@ -1190,39 +1225,6 @@ CREATE SEQUENCE public.exports_id_seq
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: -
--
@ -1299,7 +1301,6 @@ CREATE TABLE public.history_values (
value character varying,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
footprint character varying,
invoicing_profile_id integer
);
@ -1442,7 +1443,6 @@ CREATE TABLE public.invoice_items (
updated_at timestamp without time zone,
description text,
invoice_item_id integer,
footprint character varying,
object_type character varying NOT NULL,
object_id bigint NOT NULL,
main boolean
@ -1487,7 +1487,6 @@ CREATE TABLE public.invoices (
wallet_amount integer,
wallet_transaction_id integer,
coupon_id integer,
footprint character varying,
environment character varying,
invoicing_profile_id integer,
operator_profile_id integer,
@ -2142,7 +2141,6 @@ CREATE TABLE public.payment_schedule_items (
client_secret character varying,
payment_schedule_id bigint,
invoice_id bigint,
footprint character varying,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
@ -2177,7 +2175,6 @@ CREATE TABLE public.payment_schedule_objects (
object_id bigint,
payment_schedule_id bigint,
main boolean,
footprint character varying,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
@ -2214,7 +2211,6 @@ CREATE TABLE public.payment_schedules (
wallet_amount integer,
wallet_transaction_id bigint,
coupon_id bigint,
footprint character varying,
environment character varying,
invoicing_profile_id bigint,
statistic_profile_id bigint,
@ -4384,6 +4380,13 @@ ALTER TABLE ONLY public.cart_item_subscriptions ALTER COLUMN id SET DEFAULT next
ALTER TABLE ONLY public.categories ALTER COLUMN id SET DEFAULT nextval('public.categories_id_seq'::regclass);
--
-- Name: chained_elements id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.chained_elements ALTER COLUMN id SET DEFAULT nextval('public.chained_elements_id_seq'::regclass);
--
-- Name: components id; Type: DEFAULT; Schema: public; Owner: -
--
@ -4454,13 +4457,6 @@ 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);
--
-- 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: -
--
@ -5232,6 +5228,14 @@ ALTER TABLE ONLY public.categories
ADD CONSTRAINT categories_pkey PRIMARY KEY (id);
--
-- Name: chained_elements chained_elements_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.chained_elements
ADD CONSTRAINT chained_elements_pkey PRIMARY KEY (id);
--
-- Name: components components_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -5312,14 +5316,6 @@ ALTER TABLE ONLY public.exports
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: -
--
@ -6246,6 +6242,13 @@ CREATE INDEX index_cart_item_tickets_on_event_price_category ON public.cart_item
CREATE UNIQUE INDEX index_categories_on_slug ON public.categories USING btree (slug);
--
-- Name: index_chained_elements_on_element; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_chained_elements_on_element ON public.chained_elements USING btree (element_type, element_id);
--
-- Name: index_coupons_on_code; Type: INDEX; Schema: public; Owner: -
--
@ -7668,6 +7671,14 @@ ALTER TABLE ONLY public.payment_schedule_items
ADD CONSTRAINT fk_rails_4e9d79c566 FOREIGN KEY (invoice_id) REFERENCES public.invoices(id);
--
-- Name: chained_elements fk_rails_4fad806cca; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.chained_elements
ADD CONSTRAINT fk_rails_4fad806cca FOREIGN KEY (previous_id) REFERENCES public.chained_elements(id);
--
-- Name: cart_item_event_reservation_tickets fk_rails_5307e8aab8; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -8660,6 +8671,10 @@ INSERT INTO "schema_migrations" (version) VALUES
('20230307123611'),
('20230307123841'),
('20230309094535'),
('20230315095054');
('20230315095054'),
('20230323085947'),
('20230323104259'),
('20230323104727'),
('20230324090312');

View File

@ -1,6 +1,8 @@
# frozen_string_literal: false
namespace :db do
# Usage example:
# RAILS_ENV=test rails db:to_fixtures[chained_elements]
desc 'Convert development DB to Rails test fixtures'
task :to_fixtures, [:table] => :environment do |_task, args|
tables_to_skip = %w[ar_internal_metadata delayed_jobs schema_info schema_migrations].freeze
@ -11,13 +13,14 @@ namespace :db do
next if tables_to_skip.include?(table_name)
next if args.table && args.table != table_name
conter = '000'
file_path = Rails.root.join("test/fixtures/test/#{table_name}.yml")
File.open(file_path, 'w') do |file|
counter = '000'
file_path = Rails.root.join("test/fixtures/#{table_name}.yml")
File.open(file_path, File::WRONLY | File::CREAT) do |file|
rows = ActiveRecord::Base.connection.select_all("SELECT * FROM #{table_name}")
data = rows.each_with_object({}) do |record, hash|
suffix = record['id'].presence || conter.succ!
hash["#{table_name.singularize}_#{suffix}"] = record
suffix = record['id'].presence || counter.succ!
# FIXME, this is broken with jsonb columns: it records a String but a Hash must be saved
hash["#{table_name.singularize}#{suffix}"] = record
end
puts "Writing table '#{table_name}' to '#{file_path}'"
file.write(data.to_yaml)

View File

@ -89,13 +89,17 @@ namespace :fablab do
desc 'save the footprint original data'
task save_footprint_data: :environment do
[Invoice, InvoiceItem, HistoryValue, PaymentSchedule, PaymentScheduleItem].each do |klass|
klass.all.each do |item|
FootprintDebug.create!(
footprint: item.footprint,
data: FootprintService.footprint_data(klass, item),
klass: klass
[Invoice, InvoiceItem, HistoryValue, PaymentSchedule, PaymentScheduleItem, PaymentScheduleObject].each do |klass|
next if klass == PaymentScheduleObject && !ActiveRecord::Base.connection.table_exists?(PaymentScheduleObject.arel_table)
order = klass == HistoryValue ? :created_at : :id
previous = nil
klass.order(order).find_each do |item|
created = ChainedElement.create!(
element: item,
previous: previous
)
previous = created
end
end
end

View File

@ -5,7 +5,7 @@ accounting_line_43:
date: '2012-03-12 11:03:31.651441'
account_code: '5801'
account_label: Payment by card
analytical_code: ''
analytical_code:
invoice_id: 1
invoicing_profile_id: 3
debit: 10000
@ -39,7 +39,7 @@ accounting_line_45:
date: '2012-03-12 13:40:22.342717'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 2
invoicing_profile_id: 4
debit: 2000
@ -73,7 +73,7 @@ accounting_line_47:
date: '2015-06-10 11:20:01.341130'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 3
invoicing_profile_id: 7
debit: 3000
@ -107,7 +107,7 @@ accounting_line_49:
date: '2016-04-05 08:35:52.931187'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 4
invoicing_profile_id: 7
debit: 0
@ -141,7 +141,7 @@ accounting_line_51:
date: '2016-04-05 08:36:46.853368'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 5
invoicing_profile_id: 3
debit: 1500
@ -175,7 +175,7 @@ accounting_line_53:
date: '2021-01-04 14:51:21.616153'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 6
invoicing_profile_id: 8
debit: 3000
@ -209,7 +209,7 @@ accounting_line_55:
date: '2022-09-20 15:14:22.873707'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 5811
invoicing_profile_id: 3
debit: 4500
@ -260,7 +260,7 @@ accounting_line_58:
date: '2022-09-20 15:14:48.345927'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 5812
invoicing_profile_id: 7
debit: 6000
@ -294,7 +294,7 @@ accounting_line_60:
date: '2022-10-04 12:36:03.060832'
account_code: '5801'
account_label: Payment by card
analytical_code: ''
analytical_code:
invoice_id: 5816
invoicing_profile_id: 4
debit: 319
@ -345,7 +345,7 @@ accounting_line_63:
date: '2022-10-04 13:54:42.975196'
account_code: '5801'
account_label: Payment by card
analytical_code: ''
analytical_code:
invoice_id: 5817
invoicing_profile_id: 4
debit: 1295
@ -396,7 +396,7 @@ accounting_line_66:
date: '2022-10-04 14:04:12.742685'
account_code: '5801'
account_label: Payment by card
analytical_code: ''
analytical_code:
invoice_id: 5818
invoicing_profile_id: 4
debit: 1000
@ -430,7 +430,7 @@ accounting_line_68:
date: '2022-10-04 14:17:52.854636'
account_code: '5801'
account_label: Payment by card
analytical_code: ''
analytical_code:
invoice_id: 5819
invoicing_profile_id: 4
debit: 4002
@ -481,7 +481,7 @@ accounting_line_71:
date: '2022-10-04 14:25:37.291945'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 5820
invoicing_profile_id: 3
debit: 12000
@ -515,7 +515,7 @@ accounting_line_73:
date: '2022-10-04 14:32:28.204985'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 5821
invoicing_profile_id: 2
debit: 12000
@ -549,7 +549,7 @@ accounting_line_75:
date: '2022-10-04 14:35:40.584472'
account_code: '5803'
account_label: Payment by other
analytical_code: ''
analytical_code:
invoice_id: 5822
invoicing_profile_id: 2
debit: 3000

1821
test/fixtures/chained_elements.yml vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,6 @@ invoice_item_1:
updated_at: '2021-05-27 09:26:26.450083'
description: Sleede - standard, association - month
invoice_item_id:
footprint: d2b756f158d6332c32b7b262118f5bdcfd68221ab089c355e6776c1298d937b8
object_type: Subscription
object_id: 1
main: true
@ -20,7 +19,6 @@ invoice_item_2:
description: Mensuel tarif réduit - étudiant, - de 25 ans, enseignant, demandeur
d'emploi - month
invoice_item_id:
footprint: f02559738cb3674e74021ac1894e512e1864eb9fc177e885283a214fa5e0dd74
object_type: Subscription
object_id: 2
main: true
@ -32,7 +30,6 @@ invoice_item_3:
updated_at: '2021-05-27 09:26:26.465302'
description: Mensuel - standard, association - month
invoice_item_id:
footprint: e6141fbc1db017356f855ebc784cb2e084fbf82ed56a0dc295c8a39dcc2a0f92
object_type: Subscription
object_id: 3
main: true
@ -44,7 +41,6 @@ invoice_item_4:
updated_at: '2021-05-27 09:26:26.468890'
description: Formation Laser / Vinyle April 11, 2012 08:00 - 12:00 PM
invoice_item_id:
footprint: b66ade050a2ef9ebb18067ac1af2828fec2077037100d7068481e00097af4bc0
object_type: Reservation
object_id: 1
main: true
@ -56,7 +52,6 @@ invoice_item_5:
updated_at: '2021-05-27 09:26:26.472232'
description: Imprimante 3D June 15, 2015 12:00 - 01:00 PM
invoice_item_id:
footprint: a0f096de802df8d5708d4dcc23d7384ab95f246fb80e59564b2c3363db103b02
object_type: Reservation
object_id: 2
main: true
@ -68,7 +63,6 @@ invoice_item_6:
updated_at: '2021-05-27 09:26:26.475460'
description: Mensuel - standard, association - month
invoice_item_id:
footprint: 88e73e7d2f29fe8f029a646a54e5e8884ddf9cd9b207544e9f3d18c70d181749
object_type: Subscription
object_id: 4
main: true
@ -80,7 +74,6 @@ invoice_item_11702:
updated_at: '2022-09-20 15:14:23.180166'
description: Tablette lamellé-collé x 1
invoice_item_id:
footprint: 1d112a787e89d444f2817b909d7857a3a26fc2a3cd4c4404fb50bec282988a02
object_type: OrderItem
object_id: 1
main: true
@ -92,7 +85,6 @@ invoice_item_11703:
updated_at: '2022-09-20 15:14:23.289957'
description: Panneaux de MDF x 1
invoice_item_id:
footprint: 67f143564abfeab7cb93988a02987a5a2b04a2632d0f9cfde61fa39c398cd02b
object_type: OrderItem
object_id: 2
main: false
@ -104,7 +96,6 @@ invoice_item_11704:
updated_at: '2022-09-20 15:14:48.385139'
description: Panneau de contre-plaqué x 4
invoice_item_id:
footprint: ea51c614632c018f0fae53c2bf8503c71d18c082ae3246155971e19ac2db143a
object_type: OrderItem
object_id: 3
main: true
@ -116,7 +107,6 @@ invoice_item_11712:
updated_at: '2022-10-04 12:36:03.282529'
description: Filament PLA blanc x 1
invoice_item_id:
footprint: 4c5c8a1d7884502ea7791aeed1701cf3761562855d51ed19396b344c665c308b
object_type: OrderItem
object_id: 16
main: true
@ -128,7 +118,6 @@ invoice_item_11713:
updated_at: '2022-10-04 12:36:03.290235'
description: Filament PLA bleu x 1
invoice_item_id:
footprint: 12c1a2c7fdb0f4b35d0c24137e6e0bdbbb39fa5c6500aa7837c67f92084d5071
object_type: OrderItem
object_id: 17
main: false
@ -140,7 +129,6 @@ invoice_item_11714:
updated_at: '2022-10-04 13:54:42.992564'
description: Filament PLA blanc x 1
invoice_item_id:
footprint: cdb07fe1f0b986b9a53b6ec71f91a96e8b8d438592e88fd0041133b2ab46c8ca
object_type: OrderItem
object_id: 18
main: true
@ -152,7 +140,6 @@ invoice_item_11715:
updated_at: '2022-10-04 13:54:43.024326'
description: Panneau de contre-plaqué x 1
invoice_item_id:
footprint: 3ac08745b737bc370424ee9f1b68b421000eb98e0f3e65d7395d905d75de05c6
object_type: OrderItem
object_id: 19
main: false
@ -164,7 +151,6 @@ invoice_item_11716:
updated_at: '2022-10-04 14:04:12.749266'
description: Bulldozer x 1
invoice_item_id:
footprint: 1f4b6489579d7f045c846b97bc8ed402ec91f6fd7a5c2fa93b74eb7d21c7de39
object_type: OrderItem
object_id: 20
main: true
@ -176,7 +162,6 @@ invoice_item_11717:
updated_at: '2022-10-04 14:17:52.871262'
description: Sticker Hello x 2
invoice_item_id:
footprint: 0fbecff886d9c2ffc332def13fa2c8869be8a40d2be7a3126a77974bd920c563
object_type: OrderItem
object_id: 21
main: true
@ -188,7 +173,6 @@ invoice_item_11718:
updated_at: '2022-10-04 14:17:52.878780'
description: Tablette lamellé-collé x 1
invoice_item_id:
footprint: ad160b9357518b31f63661fe38998b8c1d97fda61bc744876826ae638a8142a0
object_type: OrderItem
object_id: 22
main: false
@ -200,7 +184,6 @@ invoice_item_11719:
updated_at: '2022-10-04 14:25:37.322782'
description: Tablette lamellé-collé x 3
invoice_item_id:
footprint: 409a6f0b9f67510038a8b9a407db6d09b97f12d7169d6f6f121eedb2941d1bfc
object_type: OrderItem
object_id: 11
main: true
@ -212,7 +195,6 @@ invoice_item_11720:
updated_at: '2022-10-04 14:32:28.226556'
description: Tablette lamellé-collé x 3
invoice_item_id:
footprint: 733610b9c8e33f6a63f497d867d40386c623f12a526814d09d88a96f53741b7b
object_type: OrderItem
object_id: 23
main: true
@ -224,7 +206,6 @@ invoice_item_11721:
updated_at: '2022-10-04 14:35:40.608505'
description: Panneau de 3 plis mélèze x 1
invoice_item_id:
footprint: c1ad8c20d080ebc8267ff0d1b668feb8c989c2561be75d311f29f49a03405895
object_type: OrderItem
object_id: 24
main: true

View File

@ -14,7 +14,6 @@ invoice_1:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: e4edca90b74e7d1a6f59cd62a9434027ab8cec8f3f71737938123686afaa53f6
environment: test
invoicing_profile_id: 3
operator_profile_id: 3
@ -35,7 +34,6 @@ invoice_2:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: 52f5c2cb9e58d0ad421c93437f57fe2dd364ca412c85775cd59e7510031f1091
environment: test
invoicing_profile_id: 4
operator_profile_id: 1
@ -56,7 +54,6 @@ invoice_3:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: 2396b77776092cf80e3b2c1effef36e655af63a52a781eb73f27d9f44e546bae
environment: test
invoicing_profile_id: 7
operator_profile_id: 1
@ -77,7 +74,6 @@ invoice_4:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: c0809383b304668ac5226fb502f92eb26c51701380ea9ba9526b80b0295b603d
environment: test
invoicing_profile_id: 7
operator_profile_id: 1
@ -98,7 +94,6 @@ invoice_5:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: f5d538feef1e83fd8f2b1431e7797e1d267f034e3612bdd9725a58e7ba947b27
environment: test
invoicing_profile_id: 3
operator_profile_id: 1
@ -119,7 +114,6 @@ invoice_6:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: eb22a99b5fec426dda0214bbaca3ea938fabe42c73bbf1f86712f67a5f61d236
environment: test
invoicing_profile_id: 8
operator_profile_id: 1
@ -139,7 +133,6 @@ invoice_5811:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: '094590df6330de6a2b5d2ce7230673c7178f2639ca8ceb51ba272795349fff95'
environment: development
invoicing_profile_id: 3
operator_profile_id: 1
@ -159,7 +152,6 @@ invoice_5812:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: ea5cc57a8af956f9a3e66ec1f9bd7fe5fe51e1220955cacb11a3cc99d2e6aa54
environment: development
invoicing_profile_id: 7
operator_profile_id: 1
@ -179,7 +171,6 @@ invoice_5816:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: ca8879f07cf1bd29500a9df29ce110843fb204ab0da8140bb4c6e8e908a65e0b
environment: development
invoicing_profile_id: 4
operator_profile_id: 4
@ -199,7 +190,6 @@ invoice_5817:
wallet_amount:
wallet_transaction_id:
coupon_id: 30
footprint: 838ae505dfba54f6a69cd341abf8f97fd9370c2acb81e37c6e70d98049d80646
environment: development
invoicing_profile_id: 4
operator_profile_id: 4
@ -219,7 +209,6 @@ invoice_5818:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: 93db8c6ded7066a71927b6950cf5a9ea69aff25036df3a5a4259615347f2c8b2
environment: development
invoicing_profile_id: 4
operator_profile_id: 4
@ -239,7 +228,6 @@ invoice_5819:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: bfd2f78a99aadd137f3f28fe8258a46ff8afa69b458f0a6f2dce1205fab22784
environment: development
invoicing_profile_id: 4
operator_profile_id: 4
@ -259,7 +247,6 @@ invoice_5820:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: db6a663a25e19229ee93868765e1463ec7bd7856b173c5dd326d70d98369cfc0
environment: development
invoicing_profile_id: 3
operator_profile_id: 1
@ -279,7 +266,6 @@ invoice_5821:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: 3ed9a13e5c7155bc3b186f3215b90345cc5520822728796e7c1c00ad5128ed01
environment: development
invoicing_profile_id: 2
operator_profile_id: 1
@ -299,7 +285,6 @@ invoice_5822:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: 63d069e72b4992244861e9450b0c3ba3b9b30638af972a631b81578091d2925d
environment: development
invoicing_profile_id: 2
operator_profile_id: 1

View File

@ -3,12 +3,11 @@ payment_schedule_item_105:
amount: 9474
due_date: '2021-06-14 12:24:45.836045'
state: paid
details: '{"recurring": 9466, "adjustment": 8, "other_items": 0}'
details: {"recurring": 9466, "adjustment": 8, "other_items": 0}
payment_method: card
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 6168dcf85b00be2b45a36bbb3217e8b965a179c37922962978960062eac4bec6
created_at: '2021-06-14 12:24:45.847551'
updated_at: '2021-06-14 13:00:41.302605'
@ -17,12 +16,11 @@ payment_schedule_item_106:
amount: 9466
due_date: '2021-07-14 12:24:45.836332'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: ada6f6afe6489919d193ff6030923c0d524294529f13374f9a57d5691e9669fd
created_at: '2021-06-14 12:24:45.855717'
updated_at: '2021-06-14 12:24:45.858475'
@ -32,12 +30,11 @@ payment_schedule_item_107:
amount: 9466
due_date: '2021-08-14 12:24:45.836606'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 7ca8bf5648235c8a706a01c5e788939ad5cfcc66c26782127ed1ed766379b005
created_at: '2021-06-14 12:24:45.863237'
updated_at: '2021-06-14 12:24:45.865874'
@ -46,12 +43,11 @@ payment_schedule_item_108:
amount: 9466
due_date: '2021-09-14 12:24:45.836767'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9d4925443f1537e07258140930489565542e48c39e3f9e48dd982bfae64cb759
created_at: '2021-06-14 12:24:45.869357'
updated_at: '2021-06-14 12:24:45.872088'
@ -60,12 +56,11 @@ payment_schedule_item_109:
amount: 9466
due_date: '2021-10-14 12:24:45.836900'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 157ff90f880ebc5532be14898da65dcfc227fa54aaadc37a1f123dbeefa32640
created_at: '2021-06-14 12:24:45.875500'
updated_at: '2021-06-14 12:24:45.879057'
@ -74,12 +69,11 @@ payment_schedule_item_110:
amount: 9466
due_date: '2021-11-14 12:24:45.837025'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9b162c2b342d8c82e9163202a22a405b879d4b2ad2409a61ad10942f743bc576
created_at: '2021-06-14 12:24:45.882343'
updated_at: '2021-06-14 12:24:45.884709'
@ -88,12 +82,11 @@ payment_schedule_item_111:
amount: 9466
due_date: '2021-12-14 12:24:45.837025'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9b162c2b342d8c82e9163202a22a405b879d4b2ad2409a61ad10942f743bc576
created_at: '2021-06-14 12:24:45.882343'
updated_at: '2021-06-14 12:24:45.884709'
@ -102,12 +95,11 @@ payment_schedule_item_112:
amount: 9466
due_date: '2022-01-14 12:24:45.837025'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9b162c2b342d8c82e9163202a22a405b879d4b2ad2409a61ad10942f743bc576
created_at: '2021-06-14 12:24:45.882343'
updated_at: '2021-06-14 12:24:45.884709'
@ -116,12 +108,11 @@ payment_schedule_item_113:
amount: 9466
due_date: '2022-02-14 12:24:45.837025'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9b162c2b342d8c82e9163202a22a405b879d4b2ad2409a61ad10942f743bc576
created_at: '2021-06-14 12:24:45.882343'
updated_at: '2021-06-14 12:24:45.884709'
@ -130,12 +121,11 @@ payment_schedule_item_114:
amount: 9466
due_date: '2022-03-14 12:24:45.837025'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9b162c2b342d8c82e9163202a22a405b879d4b2ad2409a61ad10942f743bc576
created_at: '2021-06-14 12:24:45.882343'
updated_at: '2021-06-14 12:24:45.884709'
@ -144,12 +134,11 @@ payment_schedule_item_115:
amount: 9466
due_date: '2022-04-14 12:24:45.837025'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9b162c2b342d8c82e9163202a22a405b879d4b2ad2409a61ad10942f743bc576
created_at: '2021-06-14 12:24:45.882343'
updated_at: '2021-06-14 12:24:45.884709'
@ -158,12 +147,11 @@ payment_schedule_item_116:
amount: 9466
due_date: '2022-05-14 12:24:45.837025'
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 12
invoice_id:
footprint: 9b162c2b342d8c82e9163202a22a405b879d4b2ad2409a61ad10942f743bc576
created_at: '2021-06-14 12:24:45.882343'
updated_at: '2021-06-14 12:24:45.884709'
@ -172,12 +160,11 @@ payment_schedule_item_117:
amount: 9474
due_date: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466, "adjustment": 8, "other_items": 0}'
details: {"recurring": 9466, "adjustment": 8, "other_items": 0}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -186,12 +173,11 @@ payment_schedule_item_118:
amount: 9466
due_date: <%= 8.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -201,12 +187,11 @@ payment_schedule_item_119:
amount: 9466
due_date: <%= 7.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -215,12 +200,11 @@ payment_schedule_item_120:
amount: 9466
due_date: <%= 6.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -229,12 +213,11 @@ payment_schedule_item_121:
amount: 9466
due_date: <%= 5.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -243,12 +226,11 @@ payment_schedule_item_122:
amount: 9466
due_date: <%= 4.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -257,12 +239,11 @@ payment_schedule_item_123:
amount: 9466
due_date: <%= 3.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -271,12 +252,11 @@ payment_schedule_item_124:
amount: 9466
due_date: <%= 2.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -285,12 +265,11 @@ payment_schedule_item_125:
amount: 9466
due_date: <%= 1.month.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: paid
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method: card
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -299,12 +278,11 @@ payment_schedule_item_126:
amount: 9466
due_date: <%= DateTime.current.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -313,12 +291,11 @@ payment_schedule_item_127:
amount: 9466
due_date: <%= 1.month.from_now.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
@ -327,11 +304,10 @@ payment_schedule_item_128:
amount: 9466
due_date: <%= 2.months.from_now.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
state: new
details: '{"recurring": 9466}'
details: {"recurring": 9466}
payment_method:
client_secret:
payment_schedule_id: 13
invoice_id:
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>

View File

@ -4,7 +4,6 @@ payment_schedule_object_10:
object_id: 5
payment_schedule_id: 12
main: true
footprint: a1ef3a0c3abac7e02bc11193458c0d1e90a5acf290c9e3b4e7c049a7efcbeb30
created_at: '2021-06-14 12:24:45.890373'
updated_at: '2021-06-14 12:24:45.894701'
@ -14,6 +13,5 @@ payment_schedule_object_11:
object_id: 6
payment_schedule_id: 13
main: true
footprint: fakefakefakefakefakefake
created_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>
updated_at: <%= 9.months.ago.utc.strftime('%Y-%m-%d %H:%M:%S.%9N Z') %>

View File

@ -6,7 +6,6 @@ payment_schedule_12:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: d4b66236895cdf18e21f64429a388050407f29bc228141ed95c89686b7daa716
environment: development
invoicing_profile_id: 9
statistic_profile_id: 9
@ -22,7 +21,6 @@ payment_schedule_13:
wallet_amount:
wallet_transaction_id:
coupon_id:
footprint: fakefakefakefakefakefake
environment: development
invoicing_profile_id: 10
statistic_profile_id: 10

View File

@ -205,7 +205,6 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
# Check the resulting invoice generation and it has right price
assert_invoice_pdf i
assert_not_nil i.debug_footprint
assert_equal (4 * 20) + (4 * 16), i.total / 100.0
end
end

View File

@ -93,7 +93,6 @@ class Events::AsUserTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
VCR.use_cassette('reserve_event_with_many_prices_and_payment_means_retrieve_invoice_from_stripe') do
stp_intent = invoice.payment_gateway_object.gateway_object.retrieve

View File

@ -139,6 +139,7 @@ class Exports::AccountingExportTest < ActionDispatch::IntegrationTest
client_code = Setting.get("accounting_payment_#{mean}_code")
assert_equal client_code, client_line[I18n.t('accounting_export.account_code')], 'Account code for client is wrong'
# the test above fails randomly... we don't know why!
client_label = Setting.get("accounting_payment_#{mean}_label")
assert_equal client_label, client_line[I18n.t('accounting_export.account_label')], 'Account label for client is wrong'

View File

@ -70,7 +70,6 @@ class Reservations::LocalPaymentTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
# notification
assert_not_empty Notification.where(attached_object: reservation)
@ -129,7 +128,6 @@ class Reservations::LocalPaymentTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
# notification
assert_not_empty Notification.where(attached_object: reservation)
@ -206,7 +204,6 @@ class Reservations::LocalPaymentTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
# notification
assert_not_empty Notification.where(attached_object: reservation)
@ -290,7 +287,6 @@ class Reservations::LocalPaymentTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
# notification
assert_not_empty Notification.where(attached_object: reservation)

View File

@ -74,7 +74,6 @@ class Reservations::LocalPaymentWithWalletTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
# notification
assert_not_empty Notification.where(attached_object: reservation)
@ -193,7 +192,6 @@ class Reservations::LocalPaymentWithWalletTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
# notification
assert_not_empty Notification.where(attached_object: reservation)

View File

@ -60,7 +60,6 @@ class Reservations::PayWithPrepaidPackTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -74,7 +74,6 @@ class Reservations::PayWithWalletTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -155,7 +154,6 @@ class Reservations::PayWithWalletTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -81,7 +81,7 @@ class Reservations::PaymentScheduleTest < ActionDispatch::IntegrationTest
assert_nil payment_schedule.wallet_amount
assert_nil payment_schedule.coupon_id
assert_equal 'test', payment_schedule.environment
assert payment_schedule.check_footprint
assert payment_schedule.check_footprint, payment_schedule.debug_footprint
assert_equal @user_without_subscription.invoicing_profile.id, payment_schedule.invoicing_profile_id
assert_equal @admin.invoicing_profile.id, payment_schedule.operator_profile_id
assert_schedule_pdf(payment_schedule)

View File

@ -109,7 +109,6 @@ class Reservations::PrivilegedUserTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -72,7 +72,6 @@ class Reservations::ReserveMachineTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -204,7 +203,6 @@ class Reservations::ReserveMachineTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -72,7 +72,6 @@ class Reservations::ReserveSpaceTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -68,7 +68,6 @@ class Reservations::ReserveTrainingTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -99,7 +99,6 @@ class Reservations::SpaceSeatsTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -168,7 +167,6 @@ class Reservations::SpaceSeatsTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -82,7 +82,6 @@ class Reservations::WithSubscriptionTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -150,7 +149,6 @@ class Reservations::WithSubscriptionTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -223,13 +221,12 @@ class Reservations::WithSubscriptionTest < ActionDispatch::IntegrationTest
invoice_item = InvoiceItem.last
assert_equal machine.prices.find_by(group_id: @vlonchamp.group_id, plan_id: nil).amount, invoice_item.amount
assert invoice_item.check_footprint
assert invoice_item.check_footprint, invoice_item.debug_footprint
# invoice assertions
item = InvoiceItem.find_by(object: reservation)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -43,7 +43,6 @@ class Store::AdminOrderForHimselfTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not @cart1.payment_gateway_object.blank?
assert_not invoice.payment_gateway_object.blank?
@ -110,7 +109,6 @@ class Store::AdminOrderForHimselfTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not @cart1.payment_gateway_object.blank?
assert_not invoice.payment_gateway_object.blank?
@ -167,16 +165,15 @@ class Store::AdminOrderForHimselfTest < ActionDispatch::IntegrationTest
# invoice_items assertions
invoice_item = InvoiceItem.last
assert invoice_item.check_footprint
assert invoice_item.check_footprint, invoice_item.debug_footprint
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
assert invoice.check_footprint
assert invoice.check_footprint, invoice.debug_footprint
# notification
assert_not_empty Notification.where(attached_object: invoice)
@ -235,7 +232,6 @@ class Store::AdminOrderForHimselfTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert @cart1.payment_gateway_object.blank?
assert invoice.payment_gateway_object.blank?

View File

@ -41,7 +41,6 @@ class Store::AdminPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert @cart1.payment_gateway_object.blank?
assert invoice.payment_gateway_object.blank?
@ -101,7 +100,6 @@ class Store::AdminPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert @cart1.payment_gateway_object.blank?
assert invoice.payment_gateway_object.blank?
@ -168,7 +166,6 @@ class Store::AdminPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -226,7 +223,6 @@ class Store::AdminPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -41,7 +41,6 @@ class Store::UserPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -98,7 +97,6 @@ class Store::UserPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_not @cart1.payment_gateway_object.blank?
assert_not invoice.payment_gateway_object.blank?
@ -167,7 +165,6 @@ class Store::UserPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?
@ -224,7 +221,6 @@ class Store::UserPayOrderTest < ActionDispatch::IntegrationTest
# invoice assertions
invoice = Invoice.last
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert invoice.payment_gateway_object.blank?
assert_not invoice.total.blank?

View File

@ -66,7 +66,6 @@ class Subscriptions::CreateAsAdminTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object_type: 'Subscription', object_id: subscription.id)
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_equal plan.amount, invoice.total, 'Invoice total price does not match the bought subscription'
end

View File

@ -73,7 +73,6 @@ class Subscriptions::CreateAsUserTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object_type: 'Subscription', object_id: subscription[:id])
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_equal plan.amount, invoice.total, 'Invoice total price does not match the bought subscription'
end
@ -178,7 +177,6 @@ class Subscriptions::CreateAsUserTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object_type: 'Subscription', object_id: subscription[:id])
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_equal plan.amount, invoice.total, 'Invoice total price does not match the bought subscription'
# wallet

View File

@ -75,7 +75,6 @@ class Subscriptions::RenewAsAdminTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object_type: 'Subscription', object_id: subscription[:id])
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_equal plan.amount, invoice.total, 'Invoice total price does not match the bought subscription'
end

View File

@ -76,7 +76,6 @@ class Subscriptions::RenewAsUserTest < ActionDispatch::IntegrationTest
item = InvoiceItem.find_by(object_type: 'Subscription', object_id: subscription[:id])
invoice = item.invoice
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
assert_equal plan.amount, invoice.total, 'Invoice total price does not match the bought subscription'
end

View File

@ -108,6 +108,5 @@ class WalletsTest < ActionDispatch::IntegrationTest
assert_equal amount, (invoice.total / 100.0), 'Avoir total does not match the amount credited to the wallet'
assert_equal amount, (invoice.invoice_items.first.amount / 100.0), 'Invoice item amount does not match'
assert_invoice_pdf invoice
assert_not_nil invoice.debug_footprint
end
end

View File

@ -0,0 +1,82 @@
# frozen_string_literal: true
require 'test_helper'
class ChainedElementTest < ActiveSupport::TestCase
test 'create a first element' do
source = Invoice.first
element = ChainedElement.create!(
element: source,
previous: nil
)
assert element.persisted?
assert_not_nil element.content
assert_not_nil element.footprint
assert_nil element.previous
assert element.content.is_a?(Hash)
FootprintService.footprint_columns(Invoice).each do |col|
if source[col].blank?
assert_not_includes element.content.keys, col
else
assert_includes element.content.keys, col
end
end
assert_includes element.content.keys, 'previous'
assert_equal source.id, element.content['id']
assert_equal source.total, element.content['total']
assert_equal source.reference, element.content['reference']
assert_equal source.payment_method, element.content['payment_method']
assert_nil element.content['previous']
assert_not element.corrupted?
end
test 'chain two elements' do
source1 = sample_reservation_invoice(users(:user2), users(:user1))
element1 = source1.chained_element
assert element1.persisted?
source2 = sample_reservation_invoice(users(:user3), users(:user1))
element2 = source2.chained_element
assert element2.persisted?
assert element2.content.is_a?(Hash)
assert_equal element1.footprint, element2.content['previous']
assert_equal element1.id, element2.previous_id
assert_not element1.corrupted?
assert_not element2.corrupted?
end
test 'chain element with children embedded json' do
source = sample_schedule(users(:user2), users(:user1))
previous = nil
source.payment_schedule_items.each do |item|
element = item.chained_element
assert element.persisted?
assert_not_nil element.content
assert_not_nil element.footprint
assert_equal previous, element.previous unless previous.nil?
assert element.content.is_a?(Hash)
FootprintService.footprint_columns(PaymentScheduleItem).each do |col|
if item[col].blank?
assert_not_includes element.content.keys, col
else
assert_includes element.content.keys, col
assert item.chained_element.content[col].is_a?(Hash) if item[col].is_a?(Hash)
end
end
assert_includes element.content.keys, 'previous'
assert_equal item.id, element.content['id']
assert_equal item.details, element.content['details']
assert_equal item.payment_schedule_id, element.content['payment_schedule_id']
assert_not_nil element.content['previous'] unless previous.nil?
assert_not element.corrupted?
previous = element
end
end
end

View File

@ -40,8 +40,13 @@ class SubscriptionExtensionAfterReservationTest < ActiveSupport::TestCase
end
test "not eligible if user doesn't have subscription" do
@user.subscriptions.destroy_all
assert_not Subscriptions::ExtensionAfterReservation.new(@reservation_training).eligible_to_extension?
user = users(:user2) # no subscriptions
reservation_training = Reservation.new(
statistic_profile: user.statistic_profile,
reservable: @training,
slots_reservations: [@slot_reservation_training]
)
assert_not Subscriptions::ExtensionAfterReservation.new(reservation_training).eligible_to_extension?
end
test 'not eligible if subscription is expired' do

View File

@ -20,10 +20,14 @@ class UsersCreditsManagerTest < ActiveSupport::TestCase
## context machine reservation
test 'machine reservation from user without subscribed plan' do
@user.subscriptions.destroy_all
user = users(:user2) # no subscriptions
reservation_machine = Reservation.new(
statistic_profile: user.statistic_profile,
reservable: @machine
)
@reservation_machine.assign_attributes(slots_reservations_attributes: [{ slot_id: @availability.slots.first }])
manager = UsersCredits::Manager.new(reservation: @reservation_machine)
reservation_machine.assign_attributes(slots_reservations_attributes: [{ slot_id: @availability.slots.first }])
manager = UsersCredits::Manager.new(reservation: reservation_machine)
assert_equal false, manager.will_use_credits?
assert_equal 0, manager.free_hours_count
@ -116,9 +120,14 @@ class UsersCreditsManagerTest < ActiveSupport::TestCase
# context training reservation
test 'training reservation from user without subscribed plan' do
@user.subscriptions.destroy_all
user = users(:user2) # no subscriptions
reservation_training = Reservation.new(
statistic_profile: user.statistic_profile,
reservable: @training,
slots_reservations_attributes: [{ slot_id: @training.availabilities.first.slots.first.id }]
)
manager = UsersCredits::Manager.new(reservation: @reservation_training)
manager = UsersCredits::Manager.new(reservation: reservation_training)
assert_equal false, manager.will_use_credits?

View File

@ -15,6 +15,9 @@ require 'helpers/invoice_helper'
require 'helpers/payment_schedule_helper'
require 'fileutils'
# We remove this constraint before running tests, otherwise it will prevent loading the fixtures into the DB
ActiveRecord::Base.connection.execute("DROP RULE IF EXISTS accounting_periods_del_protect ON #{AccountingPeriod.arel_table.name};")
VCR.configure do |config|
config.cassette_library_dir = 'test/vcr_cassettes'
config.hook_into :webmock