diff --git a/Gemfile b/Gemfile index 04bdd6a96..d10c643df 100644 --- a/Gemfile +++ b/Gemfile @@ -61,6 +61,7 @@ group :test do gem 'pdf-reader' gem 'vcr', '3.0.1' gem 'webmock' + gem 'rubyXL' end group :production, :staging do diff --git a/Gemfile.lock b/Gemfile.lock index 71529414b..0fbd391c4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -366,6 +366,9 @@ GEM ruby-rc4 (0.1.5) ruby-vips (2.0.17) ffi (~> 1.9) + rubyXL (3.4.14) + nokogiri (>= 1.10.8) + rubyzip (>= 1.3.0) rubyzip (1.3.0) safe_yaml (1.0.5) sass (3.4.25) @@ -518,6 +521,7 @@ DEPENDENCIES responders (~> 2.0) rolify rubocop (~> 0.61.1) + rubyXL rubyzip (>= 1.3.0) sass-rails (~> 5.0, >= 5.0.6) sdoc (~> 0.4.0) diff --git a/db/structure.sql b/db/structure.sql index d94aa5d6e..6ca27d22d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -108,8 +108,8 @@ SET default_tablespace = ''; CREATE TABLE public.abuses ( id integer NOT NULL, - signaled_id integer, signaled_type character varying, + signaled_id integer, first_name character varying, last_name character varying, email character varying, @@ -187,8 +187,8 @@ CREATE TABLE public.addresses ( locality character varying, country character varying, postal_code character varying, - placeable_id integer, placeable_type character varying, + placeable_id integer, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -263,8 +263,8 @@ CREATE TABLE public.ar_internal_metadata ( CREATE TABLE public.assets ( id integer NOT NULL, - viewable_id integer, viewable_type character varying, + viewable_id integer, attachment character varying, type character varying, created_at timestamp without time zone, @@ -504,8 +504,8 @@ ALTER SEQUENCE public.coupons_id_seq OWNED BY public.coupons.id; CREATE TABLE public.credits ( id integer NOT NULL, - creditable_id integer, creditable_type character varying, + creditable_id integer, plan_id integer, hours integer, created_at timestamp without time zone, @@ -1046,8 +1046,8 @@ ALTER SEQUENCE public.invoice_items_id_seq OWNED BY public.invoice_items.id; CREATE TABLE public.invoices ( id integer NOT NULL, - invoiced_id integer, invoiced_type character varying, + invoiced_id integer, stp_invoice_id character varying, total integer, created_at timestamp without time zone, @@ -1226,15 +1226,15 @@ ALTER SEQUENCE public.machines_id_seq OWNED BY public.machines.id; CREATE TABLE public.notifications ( id integer NOT NULL, receiver_id integer, - attached_object_id integer, attached_object_type character varying, + attached_object_id integer, notification_type_id integer, is_read boolean DEFAULT false, created_at timestamp without time zone, updated_at timestamp without time zone, receiver_type character varying, is_send boolean DEFAULT false, - meta_data jsonb DEFAULT '{}'::jsonb + meta_data jsonb DEFAULT '"{}"'::jsonb ); @@ -1575,8 +1575,8 @@ CREATE TABLE public.prices ( id integer NOT NULL, group_id integer, plan_id integer, - priceable_id integer, priceable_type character varying, + priceable_id integer, amount integer, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL @@ -1891,8 +1891,8 @@ CREATE TABLE public.reservations ( message text, created_at timestamp without time zone, updated_at timestamp without time zone, - reservable_id integer, reservable_type character varying, + reservable_id integer, nb_reserve_places integer, statistic_profile_id integer ); @@ -1924,8 +1924,8 @@ ALTER SEQUENCE public.reservations_id_seq OWNED BY public.reservations.id; CREATE TABLE public.roles ( id integer NOT NULL, name character varying, - resource_id integer, resource_type character varying, + resource_id integer, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -2859,8 +2859,8 @@ CREATE TABLE public.users_roles ( CREATE TABLE public.wallet_transactions ( id integer NOT NULL, wallet_id integer, - transactable_id integer, transactable_type character varying, + transactable_id integer, transaction_type character varying, amount integer, created_at timestamp without time zone NOT NULL, @@ -3919,6 +3919,14 @@ ALTER TABLE ONLY public.roles ADD CONSTRAINT roles_pkey PRIMARY KEY (id); +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.schema_migrations + ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); + + -- -- Name: settings settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -4934,29 +4942,6 @@ CREATE INDEX profiles_lower_unaccent_last_name_trgm_idx ON public.profiles USING CREATE INDEX projects_search_vector_idx ON public.projects USING gin (search_vector); --- --- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version); - - --- --- Name: accounting_periods accounting_periods_del_protect; Type: RULE; Schema: public; Owner: - --- - -CREATE RULE accounting_periods_del_protect AS - ON DELETE TO public.accounting_periods DO INSTEAD NOTHING; - - --- --- Name: accounting_periods accounting_periods_upd_protect; Type: RULE; Schema: public; Owner: - --- - -CREATE RULE accounting_periods_upd_protect AS - ON UPDATE TO public.accounting_periods DO INSTEAD NOTHING; - - -- -- Name: projects projects_search_content_trigger; Type: TRIGGER; Schema: public; Owner: - -- @@ -5443,7 +5428,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20140605125131'), ('20140605142133'), ('20140605151442'), -('20140606133116'), ('20140609092700'), ('20140609092827'), ('20140610153123'), @@ -5512,14 +5496,12 @@ INSERT INTO "schema_migrations" (version) VALUES ('20150507075620'), ('20150512123546'), ('20150520132030'), -('20150520133409'), ('20150526130729'), ('20150527153312'), ('20150529113555'), ('20150601125944'), ('20150603104502'), ('20150603104658'), -('20150603133050'), ('20150604081757'), ('20150604131525'), ('20150608142234'), @@ -5601,7 +5583,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20160905142700'), ('20160906094739'), ('20160906094847'), -('20160906145713'), ('20160915105234'), ('20161123104604'), ('20170109085345'), diff --git a/test/fixtures/trainings_availabilities.yml b/test/fixtures/trainings_availabilities.yml index 0f2b65ec7..0827e52de 100644 --- a/test/fixtures/trainings_availabilities.yml +++ b/test/fixtures/trainings_availabilities.yml @@ -19,3 +19,10 @@ trainings_availability_3: availability_id: 8 created_at: 2016-04-04 15:26:49.574308000 Z updated_at: 2016-04-04 15:26:49.574308000 Z + +trainings_availability_4: + id: 4 + training_id: 3 + availability_id: 12 + created_at: 2020-07-22 10:09:41.841162000 Z + updated_at: 2020-07-22 10:09:41.841162000 Z diff --git a/test/integration/exports/accounting_export_test.rb b/test/integration/exports/accounting_export_test.rb index dfc308b45..29a3c6632 100644 --- a/test/integration/exports/accounting_export_test.rb +++ b/test/integration/exports/accounting_export_test.rb @@ -8,7 +8,7 @@ class Exports::AccountingExportTest < ActionDispatch::IntegrationTest login_as(admin, scope: :user) end - test 'creation modification reservation and re-modification scenario' do + test 'export accounting period to ACD software' do # First, we create a new export post '/api/accounting/export', params: { diff --git a/test/integration/exports/availabilites_export_test.rb b/test/integration/exports/availabilites_export_test.rb new file mode 100644 index 000000000..25692ffe8 --- /dev/null +++ b/test/integration/exports/availabilites_export_test.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'test_helper' +require 'rubyXL' + +module Exports; end + +class Exports::AccountingExportTest < ActionDispatch::IntegrationTest + setup do + admin = User.with_role(:admin).first + login_as(admin, scope: :user) + end + + test 'export availabilities to Excel' do + # First, we create a new export + get '/api/availabilities/export_index.xlsx' + + # Check response format & status + assert_equal 200, response.status, response.body + assert_equal Mime[:json], response.content_type + + # Check the export was created correctly + res = json_response(response.body) + e = Export.where(id: res[:export_id]).first + assert_not_nil e, 'Export was not created in database' + + # Run the worker + worker = AvailabilitiesExportWorker.new + worker.perform(e.id) + + # notification + assert_not_empty Notification.where(attached_object: e) + + # resulting XLSX file + assert FileTest.exist?(e.file), 'XLSX file was not generated' + workbook = RubyXL::Parser.parse(e.file) + + # test worksheets + assert_not_nil workbook[I18n.t('export_availabilities.machines')] + assert_not_nil workbook[I18n.t('export_availabilities.trainings')] + assert_not_nil workbook[I18n.t('export_availabilities.events')] + if Setting.get('spaces_module') + assert_not_nil workbook[I18n.t('export_availabilities.spaces')] + else + assert_nil workbook[I18n.t('export_availabilities.spaces')] + end + + # test data + availability = Availability.find(13) + machines = workbook[I18n.t('export_availabilities.machines')] + assert_equal availability.start_at.to_date, machines.sheet_data[1][0].value.to_date + assert_equal I18n.l(availability.start_at, format: '%A').capitalize, machines.sheet_data[1][1].value + assert_match(/^#{availability.start_at.strftime('%H:%M')} - /, machines.sheet_data[1][2].value) + assert_includes availability.machines.map(&:name), machines.sheet_data[1][3].value + + # Clean XLSX file + require 'fileutils' + FileUtils.rm(e.file) + end +end \ No newline at end of file