diff --git a/CHANGELOG.md b/CHANGELOG.md
index 657d46872..4e6f1c5e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
- Fix a bug: (spanish) some translations are not loaded correctly
- Fix a bug: some users may not appear in the admin's general listing
- Fix a bug: Availabilities export report an erroneous number of reservations for machine availabilities (#131)
+- Fix a bug: close period reminder is sent before the first invoice's first anniversary
- Improved translations syntax according to YML specifications
- Refactored some Ruby code to match style guide
- [TODO DEPLOY] `rake fablab:fix:users_group_ids`
diff --git a/README.md b/README.md
index 1f8955085..a52dda3f7 100644
--- a/README.md
+++ b/README.md
@@ -14,9 +14,7 @@ FabManager is the Fab Lab management solution. It provides a comprehensive, web-
4.1. [General Guidelines](#general-guidelines)
4.2. [Virtual Machine Instructions](#virtual-machine-instructions)
5. [PostgreSQL](#postgresql)
-5.1. [Install PostgreSQL 9.4](#setup-postgresql)
-5.2. [Run the PostgreSQL command line interface](#run-postgresql-cli)
-5.3. [PostgreSQL Limitations](#postgresql-limitations)
+5.1. [Install PostgreSQL 9.4](#setup-postgresql)
6. [ElasticSearch](#elasticsearch)
6.1. [Install ElasticSearch](#setup-elasticsearch)
6.2. [Rebuild statistics](#rebuild-stats)
@@ -293,55 +291,8 @@ We will use docker to easily install the required version of PostgreSQL.
On MacOS, you'll have to set the host to 127.0.0.1 (or localhost).
See [environment.md](doc/environment.md) for more details.
-4. Finally, have a look at the [PostgreSQL Limitations](#postgresql-limitations) section or some errors will occurs preventing you from finishing the installation procedure.
-
-
-
-### Run the PostgreSQL command line interface
-
-You may want to access the psql command line tool to check the content of the database, or to run some maintenance routines.
-This can be achieved doing the following:
-
-1. Enter into the PostgreSQL container
- ```bash
- docker exec -it fabmanager-postgres bash
- ```
-
-2. Run the PostgreSQL administration command line interface, logged as the postgres user
-
- ```bash
- su postgres
- psql
- ```
-
-
-### PostgreSQL Limitations
-
-- While setting up the database, we'll need to activate two PostgreSQL extensions: [unaccent](https://www.postgresql.org/docs/current/static/unaccent.html) and [trigram](https://www.postgresql.org/docs/current/static/pgtrgm.html).
- This can only be achieved if the user, configured in `config/database.yml`, was granted the _SUPERUSER_ role **OR** if these extensions were white-listed.
- So here's your choices, mainly depending on your security requirements:
- - Use the default PostgreSQL super-user (postgres) as the database user. This is the default behavior in fab-manager.
- - Set your user as _SUPERUSER_; run the following command in `psql` (after replacing `username` with you user name):
-
- ```sql
- ALTER USER username WITH SUPERUSER;
- ```
-
- - Install and configure the PostgreSQL extension [pgextwlist](https://github.com/dimitri/pgextwlist).
- Please follow the instructions detailed on the extension website to whitelist `unaccent` and `trigram` for the user configured in `config/database.yml`.
-- Some users may want to use another DBMS than PostgreSQL.
- This is currently not supported, because of some PostgreSQL specific instructions that cannot be efficiently handled with the ActiveRecord ORM:
- - `app/controllers/api/members_controllers.rb@list` is using `ILIKE`
- - `app/controllers/api/invoices_controllers.rb@list` is using `ILIKE` and `date_trunc()`
- - `db/migrate/20160613093842_create_unaccent_function.rb` is using [unaccent](https://www.postgresql.org/docs/current/static/unaccent.html) and [trigram](https://www.postgresql.org/docs/current/static/pgtrgm.html) modules and defines a PL/pgSQL function (`f_unaccent()`)
- - `app/controllers/api/members_controllers.rb@search` is using `f_unaccent()` (see above) and `regexp_replace()`
- - `db/migrate/20150604131525_add_meta_data_to_notifications.rb` is using [jsonb](https://www.postgresql.org/docs/9.4/static/datatype-json.html), a PostgreSQL 9.4+ datatype.
- - `db/migrate/20160915105234_add_transformation_to_o_auth2_mapping.rb` is using [jsonb](https://www.postgresql.org/docs/9.4/static/datatype-json.html), a PostgreSQL 9.4+ datatype.
- - `db/migrate/20181217103441_migrate_settings_value_to_history_values.rb` is using `SELECT DISTINCT ON`.
- - `db/migrate/20190107111749_protect_accounting_periods.rb` is using `CREATE RULE` and `DROP RULE`.
-- If you intend to contribute to the project code, you will need to run the test suite with `rake test`.
- This also requires your user to have the _SUPERUSER_ role.
- Please see the [known issues](#known-issues) section for more information about this.
+4 . Finally, you may want to have a look at detailed informations about PostgreSQL usage in fab-manager.
+ Some information about that is available in the [PostgreSQL Readme](doc/postgresql_readme.md).
## ElasticSearch
diff --git a/app/assets/javascripts/controllers/admin/members.js.erb b/app/assets/javascripts/controllers/admin/members.js.erb
index c8c49ed49..72dde78c8 100644
--- a/app/assets/javascripts/controllers/admin/members.js.erb
+++ b/app/assets/javascripts/controllers/admin/members.js.erb
@@ -314,15 +314,14 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
// Form action on the above URL
$scope.method = 'patch';
- // List of tags associables with user
+ // List of tags joinable with user
$scope.tags = tagsPromise;
// The user to edit
$scope.user = memberPromise;
- // Should the passord be modified?
- $scope.password =
- { change: false };
+ // Should the password be modified?
+ $scope.password = { change: false };
// the user subscription
if (($scope.user.subscribed_plan != null) && ($scope.user.subscription != null)) {
@@ -576,22 +575,20 @@ Application.Controllers.controller('NewMemberController', ['$scope', '$state', '
// Form action on the above URL
$scope.method = 'post';
- // Should the passord be set manually or generated?
- $scope.password =
- { change: false };
+ // Should the password be set manually or generated?
+ $scope.password = { change: false };
// Default member's profile parameters
- $scope.user =
- { plan_interval: '' };
+ $scope.user = { plan_interval: '' };
- // Callback when the admin check/unckeck the box telling that the new user is an organization.
+ // Callback when the admin check/uncheck the box telling that the new user is an organization.
// Disable or enable the organization fields in the form, accordingly
$scope.toggleOrganization = function () {
if ($scope.user.organization) {
- if (!$scope.user.profile) { $scope.user.profile = {}; }
- return $scope.user.profile.organization = {};
+ if (!$scope.user.invoicing_profile) { $scope.user.invoicing_profile = {}; }
+ $scope.user.invoicing_profile.organization = {};
} else {
- return $scope.user.profile.organization = undefined;
+ $scope.user.invoicing_profile.organization = undefined;
}
};
@@ -609,7 +606,8 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A
$scope.admin = {
profile_attributes: {
gender: true
- }
+ },
+ invoicing_profile_attributes: {}
};
// Default parameters for AngularUI-Bootstrap datepicker
diff --git a/app/assets/templates/shared/_admin_form.html b/app/assets/templates/shared/_admin_form.html
index 469f3d41c..df886e807 100644
--- a/app/assets/templates/shared/_admin_form.html
+++ b/app/assets/templates/shared/_admin_form.html
@@ -96,11 +96,11 @@
<%= t('.body.new_account_created') %> "<%= @attached_object.profile.full_name %> <<%= @attached_object.email%>>"
-<% if @attached_object.profile.organization %> -<%= t('.body.account_for_organization') %> <%= @attached_object.profile.organization.name %>
+<% if @attached_object.invoicing_profile.organization %> +<%= t('.body.account_for_organization') %> <%= @attached_object.invoicing_profile.organization.name %>
<% end %> diff --git a/app/workers/close_period_reminder_worker.rb b/app/workers/close_period_reminder_worker.rb index d1131e329..e13835a32 100644 --- a/app/workers/close_period_reminder_worker.rb +++ b/app/workers/close_period_reminder_worker.rb @@ -2,8 +2,12 @@ class ClosePeriodReminderWorker include Sidekiq::Worker def perform + return if Invoice.count.zero? + last_period = AccountingPeriod.order(closed_at: :desc).limit(1).last - return if Invoice.count == 0 || (last_period && last_period.end_at > (Time.current - 1.year)) + first_invoice = Invoice.order(created_at: :asc).limit(1).last + return if !last_period && first_invoice.created_at > (Time.current - 1.year) + return if last_period && last_period.end_at > (Time.current - 1.year) NotificationCenter.call type: 'notify_admin_close_period_reminder', receiver: User.admins, diff --git a/db/migrate/20190521122429_create_invoicing_profiles.rb b/db/migrate/20190521122429_create_invoicing_profiles.rb new file mode 100644 index 000000000..fd072e9b9 --- /dev/null +++ b/db/migrate/20190521122429_create_invoicing_profiles.rb @@ -0,0 +1,15 @@ +class CreateInvoicingProfiles < ActiveRecord::Migration + def change + create_table :invoicing_profiles do |t| + t.references :user, index: true, foreign_key: true + t.string :first_name + t.string :last_name + t.string :email + + t.timestamps null: false + end + + add_reference :organizations, :invoicing_profile, index: true, foreign_key: true + add_reference :invoices, :invoicing_profile, index: true, foreign_key: true + end +end diff --git a/db/migrate/20190521124609_migrate_profile_to_invoicing_profile.rb b/db/migrate/20190521124609_migrate_profile_to_invoicing_profile.rb new file mode 100644 index 000000000..25357d16b --- /dev/null +++ b/db/migrate/20190521124609_migrate_profile_to_invoicing_profile.rb @@ -0,0 +1,37 @@ +class MigrateProfileToInvoicingProfile < ActiveRecord::Migration + def up + User.all.each do |u| + p = u.profile + puts "WARNING: User #{u.id} has no profile" and next unless p + + ip = InvoicingProfile.create!( + user: u, + first_name: p.first_name, + last_name: p.last_name, + email: u.email + ) + Address.find_by(placeable_id: p.id, placeable_type: 'Profile')&.update_attributes( + placeable: ip + ) + Organization.find_by(profile_id: p.id)&.update_attributes( + invoicing_profile_id: ip.id + ) + end + end + + def down + InvoicingProfile.all.each do |ip| + profile = ip.user.profile + profile.update_attributes( + first_name: ip.first_name, + last_name: ip.last_name + ) + Address.find_by(placeable_id: ip.id, placeable_type: 'InvoicingProfile')&.update_attributes( + placeable: profile + ) + Organization.find_by(invoicing_profile_id: ip.id)&.update_attributes( + profile_id: profile.id + ) + end + end +end diff --git a/db/migrate/20190522115230_migrate_user_to_invoicing_profile.rb b/db/migrate/20190522115230_migrate_user_to_invoicing_profile.rb new file mode 100644 index 000000000..b1d863e44 --- /dev/null +++ b/db/migrate/20190522115230_migrate_user_to_invoicing_profile.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +# migrate the invoices from being attached to a user to invoicing_profiles which are GDPR compliant +class MigrateUserToInvoicingProfile < ActiveRecord::Migration + def up + # first, check the footprints + check_footprints + + # if everything is ok, proceed with migration + # remove and save periods in memory + periods = backup_and_remove_periods + # migrate invoices + puts 'Migrating invoices. This may take a while...' + Invoice.order(:id).all.each do |i| + user = User.find(i.user_id) + i.update_column('invoicing_profile_id', user.invoicing_profile.id) + i.update_column('user_id', nil) + end + # chain all records + InvoiceItem.order(:id).all.each(&:chain_record) + Invoice.order(:id).all.each(&:chain_record) + # write memory dump into database + restore_periods(periods) + end + + def down + # here we don't check footprints to save processing time and because this is pointless when reverting the migrations + + # remove and save periods in memory + periods = backup_and_remove_periods + # reset invoices + Invoice.order(:created_at).all.each do |i| + i.update_column('user_id', i.invoicing_profile.user_id) + i.update_column('invoicing_profile_id', nil) + end + # chain all records + InvoiceItem.order(:id).all.each(&:chain_record) + Invoice.order(:id).all.each(&:chain_record) + # write memory dump into database + restore_periods(periods) + end + + def check_footprints + if AccountingPeriod.count.positive? + last_period = AccountingPeriod.order(start_at: 'DESC').first + puts "Checking invoices footprints from #{last_period.end_at}. This may take a while..." + Invoice.where('created_at > ?', last_period.end_at).order(:id).each do |i| + raise "Invalid footprint for invoice #{i.id}" unless i.check_footprint + end + else + puts 'Checking all invoices footprints. This may take a while...' + Invoice.order(:id).all.each do |i| + raise "Invalid footprint for invoice #{i.id}" unless i.check_footprint + end + end + end + + # will return an array of hash containing the removed periods data + def backup_and_remove_periods + return [] unless AccountingPeriod.count.positive? + + puts 'Removing accounting archives...' + # 1. remove protection for AccountingPeriods + execute("DROP RULE IF EXISTS accounting_periods_del_protect ON #{AccountingPeriod.arel_table.name};") + # 2. backup AccountingPeriods in memory + periods = [] + AccountingPeriod.all.each do |p| + periods.push( + start_at: p.start_at, + end_at: p.end_at, + closed_at: p.closed_at, + closed_by: p.closed_by + ) + end + # 3. Delete periods from database + AccountingPeriod.all.each do |ap| + execute("DELETE FROM accounting_periods WHERE ID=#{ap.id};") + end + periods + end + + def restore_periods(periods) + return unless periods.size.positive? + + # 1. recreate AccountingPeriods + puts 'Recreating accounting archives. This may take a while...' + periods.each do |p| + AccountingPeriod.create!( + start_at: p[:start_at], + end_at: p[:end_at], + closed_at: p[:closed_at], + closed_by: p[:closed_by] + ) + end + # 2. reset protection for AccountingPeriods + execute("CREATE RULE accounting_periods_del_protect AS ON DELETE TO #{AccountingPeriod.arel_table.name} DO INSTEAD NOTHING;") + end +end diff --git a/db/migrate/20190528140012_remove_user_id_from_invoice.rb b/db/migrate/20190528140012_remove_user_id_from_invoice.rb new file mode 100644 index 000000000..961ac3402 --- /dev/null +++ b/db/migrate/20190528140012_remove_user_id_from_invoice.rb @@ -0,0 +1,5 @@ +class RemoveUserIdFromInvoice < ActiveRecord::Migration + def change + remove_column :invoices, :user_id, :integer + end +end diff --git a/db/migrate/20190529120814_remove_profile_from_organization.rb b/db/migrate/20190529120814_remove_profile_from_organization.rb new file mode 100644 index 000000000..32c908c70 --- /dev/null +++ b/db/migrate/20190529120814_remove_profile_from_organization.rb @@ -0,0 +1,5 @@ +class RemoveProfileFromOrganization < ActiveRecord::Migration + def change + remove_reference :organizations, :profile, index: true, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 87bda757b..08f2bbda9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190320091148) do +ActiveRecord::Schema.define(version: 20190529120814) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -266,7 +266,6 @@ ActiveRecord::Schema.define(version: 20190320091148) do t.integer "total" t.datetime "created_at" t.datetime "updated_at" - t.integer "user_id" t.string "reference" t.string "avoir_mode" t.datetime "avoir_date" @@ -280,13 +279,25 @@ ActiveRecord::Schema.define(version: 20190320091148) do t.string "footprint" t.string "environment" t.integer "operator_id" + t.integer "invoicing_profile_id" end add_index "invoices", ["coupon_id"], name: "index_invoices_on_coupon_id", using: :btree add_index "invoices", ["invoice_id"], name: "index_invoices_on_invoice_id", using: :btree - add_index "invoices", ["user_id"], name: "index_invoices_on_user_id", using: :btree + add_index "invoices", ["invoicing_profile_id"], name: "index_invoices_on_invoicing_profile_id", using: :btree add_index "invoices", ["wallet_transaction_id"], name: "index_invoices_on_wallet_transaction_id", using: :btree + create_table "invoicing_profiles", force: :cascade do |t| + t.integer "user_id" + t.string "first_name" + t.string "last_name" + t.string "email" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "invoicing_profiles", ["user_id"], name: "index_invoicing_profiles_on_user_id", using: :btree + create_table "licences", force: :cascade do |t| t.string "name", null: false t.text "description" @@ -383,12 +394,12 @@ ActiveRecord::Schema.define(version: 20190320091148) do create_table "organizations", force: :cascade do |t| t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "profile_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "invoicing_profile_id" end - add_index "organizations", ["profile_id"], name: "index_organizations_on_profile_id", using: :btree + add_index "organizations", ["invoicing_profile_id"], name: "index_organizations_on_invoicing_profile_id", using: :btree create_table "plans", force: :cascade do |t| t.string "name" @@ -884,11 +895,13 @@ ActiveRecord::Schema.define(version: 20190320091148) do add_foreign_key "history_values", "settings" add_foreign_key "history_values", "users" add_foreign_key "invoices", "coupons" + add_foreign_key "invoices", "invoicing_profiles" add_foreign_key "invoices", "users", column: "operator_id" add_foreign_key "invoices", "wallet_transactions" + add_foreign_key "invoicing_profiles", "users" add_foreign_key "o_auth2_mappings", "o_auth2_providers" add_foreign_key "open_api_calls_count_tracings", "open_api_clients" - add_foreign_key "organizations", "profiles" + add_foreign_key "organizations", "invoicing_profiles" add_foreign_key "prices", "groups" add_foreign_key "prices", "plans" add_foreign_key "projects_spaces", "projects" diff --git a/doc/postgresql_readme.md b/doc/postgresql_readme.md new file mode 100644 index 000000000..aa593bfaf --- /dev/null +++ b/doc/postgresql_readme.md @@ -0,0 +1,53 @@ +# Detailed informations about PostgreSQL usage in fab-manager + + +## Run the PostgreSQL command line interface + +You may want to access the psql command line tool to check the content of the database, or to run some maintenance routines. +This can be achieved doing the following: + +1. Enter into the PostgreSQL container + ```bash + docker exec -it fabmanager-postgres bash + ``` + +2. Run the PostgreSQL administration command line interface, logged as the postgres user + + ```bash + su postgres + psql + ``` + + +## PostgreSQL Limitations + +- While setting up the database, we'll need to activate two PostgreSQL extensions: [unaccent](https://www.postgresql.org/docs/current/static/unaccent.html) and [trigram](https://www.postgresql.org/docs/current/static/pgtrgm.html). + This can only be achieved if the user, configured in `config/database.yml`, was granted the _SUPERUSER_ role **OR** if these extensions were white-listed. + So here's your choices, mainly depending on your security requirements: + - Use the default PostgreSQL super-user (postgres) as the database user. This is the default behavior in fab-manager. + - Set your user as _SUPERUSER_; run the following command in `psql` (after replacing `username` with you user name): + + ```sql + ALTER USER username WITH SUPERUSER; + ``` + + - Install and configure the PostgreSQL extension [pgextwlist](https://github.com/dimitri/pgextwlist). + Please follow the instructions detailed on the extension website to whitelist `unaccent` and `trigram` for the user configured in `config/database.yml`. +- If you intend to contribute to the project code, you will need to run the test suite with `rake test`. + This also requires your user to have the _SUPERUSER_ role. + Please see the [known issues](../README.md#known-issues) section for more information about this. + + + +## Using another DBMS +Some users may want to use another DBMS than PostgreSQL. +This is currently not supported, because of some PostgreSQL specific instructions that cannot be efficiently handled with the ActiveRecord ORM: + - `app/controllers/api/members_controllers.rb@list` is using `ILIKE` + - `app/controllers/api/invoices_controllers.rb@list` is using `ILIKE` and `date_trunc()` + - `db/migrate/20160613093842_create_unaccent_function.rb` is using [unaccent](https://www.postgresql.org/docs/current/static/unaccent.html) and [trigram](https://www.postgresql.org/docs/current/static/pgtrgm.html) modules and defines a PL/pgSQL function (`f_unaccent()`) + - `app/controllers/api/members_controllers.rb@search` is using `f_unaccent()` (see above) and `regexp_replace()` + - `db/migrate/20150604131525_add_meta_data_to_notifications.rb` is using [jsonb](https://www.postgresql.org/docs/9.4/static/datatype-json.html), a PostgreSQL 9.4+ datatype. + - `db/migrate/20160915105234_add_transformation_to_o_auth2_mapping.rb` is using [jsonb](https://www.postgresql.org/docs/9.4/static/datatype-json.html), a PostgreSQL 9.4+ datatype. + - `db/migrate/20181217103441_migrate_settings_value_to_history_values.rb` is using `SELECT DISTINCT ON`. + - `db/migrate/20190107111749_protect_accounting_periods.rb` is using `CREATE RULE` and `DROP RULE`. + - `db/migrate/20190522115230_migrate_user_to_invoicing_profile.rb` is using `CREATE RULE` and `DROP RULE`. \ No newline at end of file diff --git a/docker/README.md b/docker/README.md index 08a91d583..b7b08b334 100644 --- a/docker/README.md +++ b/docker/README.md @@ -96,6 +96,8 @@ You can run the following script as root to easily perform all these operations: ```bash \curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/docker/setup.sh | bash +# OR, if you don't want to install fab-manager in /apps/fabmanager, use: +\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/docker/setup.sh | bash -s "/my/custom/path" ``` ### Setup folders and env file diff --git a/lib/tasks/fablab/setup.rake b/lib/tasks/fablab/setup.rake index 6f0c75d4f..5920a4d65 100644 --- a/lib/tasks/fablab/setup.rake +++ b/lib/tasks/fablab/setup.rake @@ -30,8 +30,8 @@ namespace :fablab do if AccountingPeriod.count.positive? last_period = AccountingPeriod.order(start_at: 'DESC').first - InvoiceItem.where('created_at > ?', last_period.end_at).order(:id).each(&:chain_record) puts "Regenerating from #{last_period.end_at}..." + InvoiceItem.where('created_at > ?', last_period.end_at).order(:id).each(&:chain_record) else puts '(Re)generating all footprint...' InvoiceItem.order(:id).all.each(&:chain_record) diff --git a/test/fixtures/addresses.yml b/test/fixtures/addresses.yml index 54549dd21..e6cbab1a7 100644 --- a/test/fixtures/addresses.yml +++ b/test/fixtures/addresses.yml @@ -8,7 +8,7 @@ address_1: country: postal_code: placeable_id: 2 - placeable_type: Profile + placeable_type: InvoicingProfile created_at: 2016-04-04 15:06:22.166469000 Z updated_at: 2016-04-04 15:06:22.166469000 Z @@ -21,7 +21,7 @@ address_2: country: postal_code: placeable_id: 4 - placeable_type: Profile + placeable_type: InvoicingProfile created_at: 2016-04-04 15:10:42.353039000 Z updated_at: 2016-04-04 15:10:42.353039000 Z @@ -34,7 +34,7 @@ address_3: country: postal_code: placeable_id: 5 - placeable_type: Profile + placeable_type: InvoicingProfile created_at: 2016-04-04 15:14:08.579603000 Z updated_at: 2016-04-04 15:14:08.579603000 Z @@ -47,7 +47,7 @@ address_4: country: postal_code: placeable_id: 3 - placeable_type: Profile + placeable_type: InvoicingProfile created_at: 2016-04-05 08:35:18.597812000 Z updated_at: 2016-04-05 08:35:18.597812000 Z diff --git a/test/fixtures/invoices.yml b/test/fixtures/invoices.yml index 6f90b2a03..71c588753 100644 --- a/test/fixtures/invoices.yml +++ b/test/fixtures/invoices.yml @@ -7,7 +7,7 @@ invoice_1: total: 10000 created_at: 2012-03-12 11:03:31.651441000 Z updated_at: 2012-03-12 11:03:31.651441000 Z - user_id: 3 + invoicing_profile_id: 3 reference: 1604001/VL avoir_mode: avoir_date: @@ -15,7 +15,7 @@ invoice_1: type: subscription_to_expire: description: - footprint: 9b1d216a49a65f5428c92af10e284d6dfe4070f6e65e5eacd735ef770540a16a + footprint: d477d23a473c565e2c379263d4c86c9cc80cdd88adc9a3ff7246afccec0e2a18 environment: test operator_id: @@ -27,7 +27,7 @@ invoice_2: total: 2000 created_at: 2012-03-12 13:40:22.342717000 Z updated_at: 2012-03-12 13:40:22.342717000 Z - user_id: 4 + invoicing_profile_id: 4 reference: '1604002' avoir_mode: avoir_date: @@ -35,7 +35,7 @@ invoice_2: type: subscription_to_expire: description: - footprint: 32c09fe7ba92501f9239c111abd6688cb7d4ea5fe16c201f56d8d28546031804 + footprint: 4cef4ec78543075af4d782ef919ca95ccbdfbd3bad91f2dfe01fe9b5113eb4d4 environment: test operator_id: @@ -47,7 +47,7 @@ invoice_3: total: 3000 created_at: 2015-06-10 11:20:01.341130000 Z updated_at: 2015-06-10 11:20:01.341130000 Z - user_id: 7 + invoicing_profile_id: 7 reference: '1203001' avoir_mode: avoir_date: @@ -55,7 +55,7 @@ invoice_3: type: subscription_to_expire: description: - footprint: bbb731b181eafd9a78b0b610afeddd3c92f55fcc11b9d58a2d4956cb30b28ee0 + footprint: 295f687cfc1df1c9dfe6759f0c3a4d7e92bc8959ee909d944537dffa6b8a0a5e environment: test operator_id: @@ -68,7 +68,7 @@ invoice_4: total: 0 created_at: 2016-04-05 08:35:52.931187000 Z updated_at: 2016-04-05 08:35:52.931187000 Z - user_id: 7 + invoicing_profile_id: 7 reference: '1203002' avoir_mode: avoir_date: @@ -76,7 +76,7 @@ invoice_4: type: subscription_to_expire: description: - footprint: 0b4afc997a22975102441c9dc3635a43bb098d31086f79189751d12e0fb0078c + footprint: 18a80a204730011d5c5b753bf9ff86bda49acf7acbdcf31cf37d67df9ae6e53e environment: test operator_id: @@ -88,7 +88,7 @@ invoice_5: total: 1500 created_at: 2016-04-05 08:36:46.853368000 Z updated_at: 2016-04-05 08:36:46.853368000 Z - user_id: 3 + invoicing_profile_id: 3 reference: '1506031' avoir_mode: avoir_date: @@ -96,6 +96,6 @@ invoice_5: type: subscription_to_expire: description: - footprint: b580117a83436c91475f06ced6c043ce9677c86c2c04cd41ed10860fb214ec71 + footprint: c94afc0e5054da75522d438e8f33e6fcadc94c960ce7bdcf4cb4d83e7ca2a8e9 environment: test operator_id: diff --git a/test/fixtures/invoicing_profiles.yml b/test/fixtures/invoicing_profiles.yml new file mode 100644 index 000000000..aede0635b --- /dev/null +++ b/test/fixtures/invoicing_profiles.yml @@ -0,0 +1,48 @@ +admin: + id: 1 + user_id: 1 + first_name: admin + last_name: admin + email: admin@fab-manager.com + +jdupont: + id: 2 + user_id: 2 + first_name: Jean + last_name: Dupont + email: jean.dupond@gmail.com + +kdumas: + id: 4 + user_id: 4 + first_name: Kevin + last_name: Dumas + email: kevin.dumas@orange.fr + +vlonchamp: + id: 5 + user_id: 5 + first_name: Vanessa + last_name: Lonchamp + email: vanessa.lonchamp@sfr.fr + +gpartenaire: + id: 6 + user_id: 6 + first_name: Gilbert + last_name: Partenaire + email: gilbert.partenaire@nicolas.com + +pdurand: + id: 3 + user_id: 3 + first_name: Paulette + last_name: Durand + email: paulette.durand@hotmail.fr + +lseguin: + id: 7 + user_id: 7 + first_name: Lucile + last_name: Seguin + email: lucile.seguin@live.fr diff --git a/test/fixtures/organizations.yml b/test/fixtures/organizations.yml index beca74d5b..0ea72a682 100644 --- a/test/fixtures/organizations.yml +++ b/test/fixtures/organizations.yml @@ -1,4 +1,4 @@ casemate: id: 1 name: La Casemate - profile_id: 7 + invoicing_profile_id: 7 diff --git a/test/integration/admins_test.rb b/test/integration/admins_test.rb index 2d874790e..458f56f3a 100644 --- a/test/integration/admins_test.rb +++ b/test/integration/admins_test.rb @@ -26,6 +26,8 @@ class AdminsTest < ActionDispatch::IntegrationTest gender: true, birthday: '1999-09-19', phone: '0547124852', + }, + invoicing_profile_attributes: { address_attributes: { address: '6 Avenue Henri de Bournazel, 19000 Tulle' } diff --git a/test/models/invoicing_profile_test.rb b/test/models/invoicing_profile_test.rb new file mode 100644 index 000000000..2cf8236d0 --- /dev/null +++ b/test/models/invoicing_profile_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class InvoicingProfileTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 7387deaed..3c7af7e67 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -99,6 +99,18 @@ class ActiveSupport::TestCase else assert_equal invoice.total, ht_amount, 'VAT information was rendered in the PDF file despite that VAT was disabled' end + + # check the recipient & the address + if invoice.invoicing_profile.organization + assert lines.first.include?(invoice.invoicing_profile.organization.name), 'On the PDF invoice, organization name is invalid' + assert invoice.invoicing_profile.organization.address.address.include?(lines[2].split(' ').last.strip), 'On the PDF invoice, organization address is invalid' + else + assert lines.first.include?(invoice.invoicing_profile.full_name), 'On the PDF invoice, customer name is invalid' + assert invoice.invoicing_profile.address.address.include?(lines[2].split(' ').last.strip), 'On the PDF invoice, customer address is invalid' + end + # check the email + assert lines[1].include?(invoice.invoicing_profile.email), 'On the PDF invoice, email is invalid' + File.delete(invoice.file) end