mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-19 13:54:25 +01:00
moving organization & address to invoicingProfile + refactored doc about postgre
This commit is contained in:
parent
142e07f3c9
commit
a211ad39ff
55
README.md
55
README.md
@ -14,9 +14,7 @@ FabManager is the Fab Lab management solution. It provides a comprehensive, web-
|
||||
4.1. [General Guidelines](#general-guidelines)<br/>
|
||||
4.2. [Virtual Machine Instructions](#virtual-machine-instructions)
|
||||
5. [PostgreSQL](#postgresql)<br/>
|
||||
5.1. [Install PostgreSQL 9.4](#setup-postgresql)<br/>
|
||||
5.2. [Run the PostgreSQL command line interface](#run-postgresql-cli)<br/>
|
||||
5.3. [PostgreSQL Limitations](#postgresql-limitations)
|
||||
5.1. [Install PostgreSQL 9.4](#setup-postgresql)
|
||||
6. [ElasticSearch](#elasticsearch)<br/>
|
||||
6.1. [Install ElasticSearch](#setup-elasticsearch)<br/>
|
||||
6.2. [Rebuild statistics](#rebuild-stats)<br/>
|
||||
@ -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.
|
||||
|
||||
|
||||
<a name="run-postgresql-cli"></a>
|
||||
### 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
|
||||
```
|
||||
|
||||
<a name="postgresql-limitations"></a>
|
||||
### 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).
|
||||
|
||||
<a name="elasticsearch"></a>
|
||||
## ElasticSearch
|
||||
|
@ -609,7 +609,8 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A
|
||||
$scope.admin = {
|
||||
profile_attributes: {
|
||||
gender: true
|
||||
}
|
||||
},
|
||||
invoicing_profile_attributes: {}
|
||||
};
|
||||
|
||||
// Default parameters for AngularUI-Bootstrap datepicker
|
||||
|
@ -96,11 +96,11 @@
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-map-marker"></i> </span>
|
||||
<input type="hidden"
|
||||
name="admin[profile_attributes][address_attributes][id]"
|
||||
ng-value="admin.profile_attributes.address.id" />
|
||||
<input ng-model="admin.profile_attributes.address_attributes.address"
|
||||
name="admin[invoicing_profile_attributes][address_attributes][id]"
|
||||
ng-value="admin.invoicing_profile_attributes.address.id" />
|
||||
<input ng-model="admin.invoicing_profile_attributes.address_attributes.address"
|
||||
type="text"
|
||||
name="admin[profile_attributes][address_attributes][address]"
|
||||
name="admin[invoicing_profile_attributes][address_attributes][address]"
|
||||
class="form-control"
|
||||
id="user_address"
|
||||
placeholder="{{ 'address' | translate }}">
|
||||
|
@ -165,38 +165,38 @@
|
||||
<span class="help-block" ng-show="userForm['user[password_confirmation]'].$error.match" translate>{{ 'confirmation_mismatch_with_password' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="user.profile.organization" ng-class="{'has-error': userForm['user[profile_attributes][organization_attributes][name]'].$dirty && userForm['user[profile_attributes][organization_attributes][name]'].$invalid}">
|
||||
<div class="form-group" ng-if="user.profile.organization" ng-class="{'has-error': userForm['user[invoicing_profile_attributes][organization_attributes][name]'].$dirty && userForm['user[invoicing_profile_attributes][organization_attributes][name]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-building-o"></i> <span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<input type="hidden"
|
||||
name="user[profile_attributes][organization_attributes][id]"
|
||||
name="user[invoicing_profile_attributes][organization_attributes][id]"
|
||||
ng-value="user.profile.organization.id" />
|
||||
<input type="text"
|
||||
name="user[profile_attributes][organization_attributes][name]"
|
||||
name="user[invoicing_profile_attributes][organization_attributes][name]"
|
||||
ng-model="user.profile.organization.name"
|
||||
class="form-control"
|
||||
placeholder="{{ 'organization_name' | translate }}"
|
||||
ng-required="user.profile.organization"
|
||||
ng-disabled="preventField['profile.organization_name'] && user.profile.organization.name && !userForm['user[profile_attributes][organization_attributes][name]'].$dirty">
|
||||
ng-disabled="preventField['profile.organization_name'] && user.profile.organization.name && !userForm['user[invoicing_profile_attributes][organization_attributes][name]'].$dirty">
|
||||
</div>
|
||||
<span class="help-block" ng-show="userForm['user[profile_attributes][organization_attributes][name]'].$dirty && userForm['user[profile_attributes][organization_attributes][name]'].$error.required" translate>{{ 'organization_name_is_required' }}</span>
|
||||
<span class="help-block" ng-show="userForm['user[invoicing_][organization_attributes][name]'].$dirty && userForm['user[invoicing_profile_attributes][organization_attributes][name]'].$error.required" translate>{{ 'organization_name_is_required' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="user.profile.organization" ng-class="{'has-error': userForm['user[profile_attributes][organization_attributes][address_attributes][address]'].$dirty && userForm['user[profile_attributes][organization_attributes][address_attributes][address]'].$invalid}">
|
||||
<div class="form-group" ng-if="user.profile.organization" ng-class="{'has-error': userForm['user[invoicing_profile_attributes][organization_attributes][address_attributes][address]'].$dirty && userForm['user[invoicing_profile_attributes][organization_attributes][address_attributes][address]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-map-marker"></i> <span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<input type="hidden"
|
||||
name="user[profile_attributes][organization_attributes][address_attributes][id]"
|
||||
name="user[invoicing_profile_attributes][organization_attributes][address_attributes][id]"
|
||||
ng-value="user.profile.organization.address.id" />
|
||||
<input type="text"
|
||||
name="user[profile_attributes][organization_attributes][address_attributes][address]"
|
||||
name="user[invoicing_profile_attributes][organization_attributes][address_attributes][address]"
|
||||
ng-model="user.profile.organization.address.address"
|
||||
class="form-control"
|
||||
placeholder="{{ 'organization_address' | translate }}"
|
||||
ng-required="user.profile.organization"
|
||||
ng-disabled="preventField['profile.organization_address'] && user.profile.organization.address.address && !userForm['user[profile_attributes][organization_attributes][address_attributes][address]'].$dirty">
|
||||
ng-disabled="preventField['profile.organization_address'] && user.profile.organization.address.address && !userForm['user[invoicing_profile_attributes][organization_attributes][address_attributes][address]'].$dirty">
|
||||
</div>
|
||||
<span class="help-block" ng-show="userForm['user[profile_attributes][organization_attributes][address_attributes][address]'].$dirty && userForm['user[profile_attributes][organization_attributes][address_attributes][address]'].$error.required" translate>{{ 'organization_address_is_required' }}</span>
|
||||
<span class="help-block" ng-show="userForm['user[invoicing_profile_attributes][organization_attributes][address_attributes][address]'].$dirty && userForm['user[invoicing_profile_attributes][organization_attributes][address_attributes][address]'].$error.required" translate>{{ 'organization_address_is_required' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': userForm['user[profile_attributes][birthday]'].$dirty && userForm['user[profile_attributes][birthday]'].$invalid}">
|
||||
@ -224,14 +224,14 @@
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-map-marker"></i> </span>
|
||||
<input type="hidden"
|
||||
name="user[profile_attributes][address_attributes][id]"
|
||||
name="user[invoicing_profile_attributes][address_attributes][id]"
|
||||
ng-value="user.profile.address.id" />
|
||||
<input type="text"
|
||||
name="user[profile_attributes][address_attributes][address]"
|
||||
name="user[invoicing_profile_attributes][address_attributes][address]"
|
||||
ng-model="user.profile.address.address"
|
||||
class="form-control"
|
||||
id="user_address"
|
||||
ng-disabled="preventField['profile.address'] && user.profile.address.address && !userForm['user[profile_attributes][address_attributes][address]'].$dirty"
|
||||
ng-disabled="preventField['profile.address'] && user.profile.address.address && !userForm['user[invoicing_profile_attributes][address_attributes][address]'].$dirty"
|
||||
placeholder="{{ 'address' | translate }}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,7 +45,10 @@ class API::AdminsController < API::ApiController
|
||||
private
|
||||
|
||||
def admin_params
|
||||
params.require(:admin).permit(:username, :email, profile_attributes: [:first_name, :last_name, :gender,
|
||||
:birthday, :phone, address_attributes: [:address]])
|
||||
params.require(:admin).permit(
|
||||
:username, :email,
|
||||
profile_attributes: %i[first_name last_name gender birthday phone],
|
||||
invoicing_profile_attributes: [address_attributes: [:address]]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -195,10 +195,11 @@ class API::MembersController < API::ApiController
|
||||
:software_mastered, :website, :job, :facebook, :twitter,
|
||||
:google_plus, :viadeo, :linkedin, :instagram, :youtube, :vimeo,
|
||||
:dailymotion, :github, :echosciences, :pinterest, :lastfm, :flickr,
|
||||
user_avatar_attributes: %i[id attachment destroy],
|
||||
address_attributes: %i[id address],
|
||||
organization_attributes: [:id, :name,
|
||||
address_attributes: %i[id address]]])
|
||||
user_avatar_attributes: %i[id attachment destroy]],
|
||||
invoicing_profile_attributes: [
|
||||
address_attributes: %i[id address],
|
||||
organization_attributes: [:id, :name, address_attributes: %i[id address]]
|
||||
])
|
||||
|
||||
elsif current_user.admin?
|
||||
params.require(:user).permit(:username, :email, :password, :password_confirmation,
|
||||
@ -208,10 +209,11 @@ class API::MembersController < API::ApiController
|
||||
:software_mastered, :website, :job, :facebook, :twitter,
|
||||
:google_plus, :viadeo, :linkedin, :instagram, :youtube, :vimeo,
|
||||
:dailymotion, :github, :echosciences, :pinterest, :lastfm, :flickr,
|
||||
user_avatar_attributes: %i[id attachment destroy],
|
||||
address_attributes: %i[id address],
|
||||
organization_attributes: [:id, :name,
|
||||
address_attributes: %i[id address]]])
|
||||
user_avatar_attributes: %i[id attachment destroy]],
|
||||
invoicing_profile_attributes: [
|
||||
address_attributes: %i[id address],
|
||||
organization_attributes: [:id, :name, address_attributes: %i[id address]]
|
||||
])
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -32,12 +32,12 @@ class ApplicationController < ActionController::Base
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.permit(:sign_up,
|
||||
keys: [
|
||||
{ profile_attributes: [
|
||||
:phone, :last_name, :first_name, :gender, :birthday,
|
||||
:interest, :software_mastered, organization_attributes: [
|
||||
:name, address_attributes: [:address]
|
||||
{
|
||||
profile_attributes: %i[phone last_name first_name gender birthday interest software_mastered],
|
||||
invoicing_profile_attributes: [
|
||||
organization_attributes: [:name, address_attributes: [:address]]
|
||||
]
|
||||
] },
|
||||
},
|
||||
:username, :is_allow_contact, :is_allow_newsletter, :cgu, :group_id
|
||||
])
|
||||
end
|
||||
|
@ -1,7 +1,9 @@
|
||||
class InvoicingProfile < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
has_one :address, as: :placeable, dependent: :destroy
|
||||
accepts_nested_attributes_for :address, allow_destroy: true
|
||||
has_one :organization, dependent: :destroy
|
||||
accepts_nested_attributes_for :organization, allow_destroy: false
|
||||
has_many :invoices, dependent: :destroy
|
||||
|
||||
|
||||
|
@ -7,11 +7,6 @@ class Profile < ActiveRecord::Base
|
||||
accepts_nested_attributes_for :user_avatar,
|
||||
allow_destroy: true,
|
||||
reject_if: proc { |attributes| attributes['attachment'].blank? }
|
||||
has_one :address, as: :placeable, dependent: :destroy
|
||||
accepts_nested_attributes_for :address, allow_destroy: true
|
||||
|
||||
has_one :organization, dependent: :destroy
|
||||
accepts_nested_attributes_for :organization, allow_destroy: false
|
||||
|
||||
validates :first_name, presence: true, length: { maximum: 30 }
|
||||
validates :last_name, presence: true, length: { maximum: 30 }
|
||||
|
@ -22,6 +22,7 @@ class User < ActiveRecord::Base
|
||||
accepts_nested_attributes_for :profile
|
||||
|
||||
has_one :invoicing_profile, dependent: :nullify
|
||||
accepts_nested_attributes_for :invoicing_profile
|
||||
|
||||
has_many :my_projects, foreign_key: :author_id, class_name: 'Project', dependent: :destroy
|
||||
has_many :project_users, dependent: :destroy
|
||||
|
@ -52,23 +52,23 @@ class PDF::Invoice < Prawn::Document
|
||||
end
|
||||
|
||||
# user/organization's information
|
||||
if invoice&.user&.profile&.organization
|
||||
name = invoice.user.profile.organization.name
|
||||
full_name = "#{name} (#{invoice.user.profile.full_name})"
|
||||
if invoice&.invoicing_profile&.organization
|
||||
name = invoice.invoicing_profile.organization.name
|
||||
full_name = "#{name} (#{invoice.invoicing_profile.full_name})"
|
||||
else
|
||||
name = invoice.user.profile.full_name
|
||||
name = invoice.invoicing_profile.full_name
|
||||
full_name = name
|
||||
end
|
||||
|
||||
address = if invoice&.user&.profile&.organization&.address
|
||||
invoice.user.profile.organization.address.address
|
||||
elsif invoice&.user&.profile&.address
|
||||
invoice.user.profile.address.address
|
||||
address = if invoice&.invoicing_profile&.organization&.address
|
||||
invoice.invoicing_profile.organization.address.address
|
||||
elsif invoice&.invoicing_profile&.address
|
||||
invoice.invoicing_profile.address.address
|
||||
else
|
||||
''
|
||||
end
|
||||
|
||||
text_box "<b>#{name}</b>\n#{invoice.user.email}\n#{address}",
|
||||
text_box "<b>#{name}</b>\n#{invoice.invoicing_profile.email}\n#{address}",
|
||||
at: [bounds.width - 130, bounds.top - 49],
|
||||
width: 130,
|
||||
align: :right,
|
||||
|
@ -6,8 +6,10 @@ json.profile_attributes do
|
||||
json.gender admin.profile.gender
|
||||
json.birthday admin.profile.birthday if admin.profile.birthday
|
||||
json.phone admin.profile.phone
|
||||
json.user_avatar do
|
||||
json.id admin.profile.user_avatar.id
|
||||
json.attachment_url admin.profile.user_avatar.attachment_url
|
||||
end if admin.profile.user_avatar
|
||||
if admin.profile.user_avatar
|
||||
json.user_avatar do
|
||||
json.id admin.profile.user_avatar.id
|
||||
json.attachment_url admin.profile.user_avatar.attachment_url
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,53 +2,71 @@ json.extract! member, :id, :username, :email, :group_id
|
||||
json.role member.roles.first.name
|
||||
json.name member.profile.full_name
|
||||
json.need_completion member.need_completion?
|
||||
|
||||
json.profile do
|
||||
json.id member.profile.id
|
||||
json.user_avatar do
|
||||
json.id member.profile.user_avatar.id
|
||||
json.attachment_url member.profile.user_avatar.attachment_url
|
||||
end if member.profile.user_avatar
|
||||
if member.profile.user_avatar
|
||||
json.user_avatar do
|
||||
json.id member.profile.user_avatar.id
|
||||
json.attachment_url member.profile.user_avatar.attachment_url
|
||||
end
|
||||
end
|
||||
json.first_name member.profile.first_name
|
||||
json.last_name member.profile.last_name
|
||||
json.gender member.profile.gender.to_s
|
||||
json.birthday member.profile.birthday.to_date.iso8601 if member.profile.birthday
|
||||
json.interest member.profile.interest
|
||||
json.software_mastered member.profile.software_mastered
|
||||
json.address do
|
||||
json.id member.profile.address.id
|
||||
json.address member.profile.address.address
|
||||
end if member.profile.address
|
||||
json.phone member.profile.phone
|
||||
json.website member.profile.website
|
||||
json.job member.profile.job
|
||||
json.extract! member.profile, :facebook, :twitter, :google_plus, :viadeo, :linkedin, :instagram, :youtube, :vimeo, :dailymotion, :github, :echosciences, :pinterest, :lastfm, :flickr
|
||||
json.organization do
|
||||
json.id member.profile.organization.id
|
||||
json.name member.profile.organization.name
|
||||
json.address do
|
||||
json.id member.profile.organization.address.id
|
||||
json.address member.profile.organization.address.address
|
||||
end if member.profile.organization.address
|
||||
end if member.profile.organization
|
||||
|
||||
end
|
||||
json.subscribed_plan do
|
||||
json.partial! 'api/shared/plan', plan: member.subscribed_plan
|
||||
end if member.subscribed_plan
|
||||
json.subscription do
|
||||
json.id member.subscription.id
|
||||
json.expired_at member.subscription.expired_at.iso8601
|
||||
json.canceled_at member.subscription.canceled_at.iso8601 if member.subscription.canceled_at
|
||||
json.stripe member.subscription.stp_subscription_id.present?
|
||||
json.plan do
|
||||
json.id member.subscription.plan.id
|
||||
json.base_name member.subscription.plan.base_name
|
||||
json.name member.subscription.plan.name
|
||||
json.interval member.subscription.plan.interval
|
||||
json.interval_count member.subscription.plan.interval_count
|
||||
json.amount member.subscription.plan.amount ? (member.subscription.plan.amount / 100.0) : 0
|
||||
|
||||
json.invoicing_profile do
|
||||
if member.invoicing_profile.address
|
||||
json.address do
|
||||
json.id member.invoicing_profile.address.id
|
||||
json.address member.invoicing_profile.address.address
|
||||
end
|
||||
end
|
||||
end if member.subscription
|
||||
|
||||
if member.invoicing_profile.organization
|
||||
json.organization do
|
||||
json.id member.invoicing_profile.organization.id
|
||||
json.name member.invoicing_profile.organization.name
|
||||
if member.invoicing_profile.organization.address
|
||||
json.address do
|
||||
json.id member.invoicing_profile.organization.address.id
|
||||
json.address member.invoicing_profile.organization.address.address
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if member.subscribed_plan
|
||||
json.subscribed_plan do
|
||||
json.partial! 'api/shared/plan', plan: member.subscribed_plan
|
||||
end
|
||||
end
|
||||
|
||||
if member.subscription
|
||||
json.subscription do
|
||||
json.id member.subscription.id
|
||||
json.expired_at member.subscription.expired_at.iso8601
|
||||
json.canceled_at member.subscription.canceled_at.iso8601 if member.subscription.canceled_at
|
||||
json.stripe member.subscription.stp_subscription_id.present?
|
||||
json.plan do
|
||||
json.id member.subscription.plan.id
|
||||
json.base_name member.subscription.plan.base_name
|
||||
json.name member.subscription.plan.name
|
||||
json.interval member.subscription.plan.interval
|
||||
json.interval_count member.subscription.plan.interval_count
|
||||
json.amount member.subscription.plan.amount ? (member.subscription.plan.amount / 100.0) : 0
|
||||
end
|
||||
end
|
||||
end
|
||||
json.training_credits member.training_credits do |tc|
|
||||
json.training_id tc.creditable_id
|
||||
end
|
||||
|
@ -4,6 +4,7 @@ class CreateInvoicingProfiles < ActiveRecord::Migration
|
||||
t.references :user, index: true, foreign_key: true
|
||||
t.string :first_name
|
||||
t.string :last_name
|
||||
t.string :email
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
|
@ -7,12 +7,13 @@ class MigrateProfileToInvoicingProfile < ActiveRecord::Migration
|
||||
ip = InvoicingProfile.create!(
|
||||
user: u,
|
||||
first_name: p.first_name,
|
||||
last_name: p.last_name
|
||||
last_name: p.last_name,
|
||||
email: u.email
|
||||
)
|
||||
p.address&.update_attributes(
|
||||
Address.find_by(placeable_id: p.id, placeable_type: 'Profile')&.update_attributes(
|
||||
placeable: ip
|
||||
)
|
||||
p.organization&.update_attributes(
|
||||
Organization.find_by(profile_id: p.id)&.update_attributes(
|
||||
invoicing_profile_id: ip.id
|
||||
)
|
||||
end
|
||||
@ -25,10 +26,10 @@ class MigrateProfileToInvoicingProfile < ActiveRecord::Migration
|
||||
first_name: ip.first_name,
|
||||
last_name: ip.last_name
|
||||
)
|
||||
ip.address&.update_attributes(
|
||||
Address.find_by(placeable_id: ip.id, placeable_type: 'InvoicingProfile')&.update_attributes(
|
||||
placeable: profile
|
||||
)
|
||||
ip.organization&.update_attributes(
|
||||
Organization.find_by(invoicing_profile_id: ip.id)&.update_attributes(
|
||||
profile_id: profile.id
|
||||
)
|
||||
end
|
||||
|
@ -12,7 +12,8 @@ class MigrateUserToInvoicingProfile < ActiveRecord::Migration
|
||||
# migrate invoices
|
||||
puts 'Migrating invoices. This may take a while...'
|
||||
Invoice.order(:id).all.each do |i|
|
||||
i.update_column('invoicing_profile_id', i.user.invoicing_profile.id)
|
||||
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
|
||||
|
@ -0,0 +1,5 @@
|
||||
class RemoveProfileFromOrganization < ActiveRecord::Migration
|
||||
def change
|
||||
remove_reference :organizations, :profile, index: true, foreign_key: true
|
||||
end
|
||||
end
|
186
db/schema.rb
186
db/schema.rb
@ -11,12 +11,12 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
ActiveRecord::Schema.define(version: 20190529120814) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
enable_extension "unaccent"
|
||||
enable_extension "pg_trgm"
|
||||
enable_extension "unaccent"
|
||||
|
||||
create_table "abuses", force: :cascade do |t|
|
||||
t.integer "signaled_id"
|
||||
@ -44,14 +44,14 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
end
|
||||
|
||||
create_table "addresses", force: :cascade do |t|
|
||||
t.string "address"
|
||||
t.string "street_number"
|
||||
t.string "route"
|
||||
t.string "locality"
|
||||
t.string "country"
|
||||
t.string "postal_code"
|
||||
t.string "address", limit: 255
|
||||
t.string "street_number", limit: 255
|
||||
t.string "route", limit: 255
|
||||
t.string "locality", limit: 255
|
||||
t.string "country", limit: 255
|
||||
t.string "postal_code", limit: 255
|
||||
t.integer "placeable_id"
|
||||
t.string "placeable_type"
|
||||
t.string "placeable_type", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@ -67,9 +67,9 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
|
||||
create_table "assets", force: :cascade do |t|
|
||||
t.integer "viewable_id"
|
||||
t.string "viewable_type"
|
||||
t.string "attachment"
|
||||
t.string "type"
|
||||
t.string "viewable_type", limit: 255
|
||||
t.string "attachment", limit: 255
|
||||
t.string "type", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@ -86,12 +86,12 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
create_table "availabilities", force: :cascade do |t|
|
||||
t.datetime "start_at"
|
||||
t.datetime "end_at"
|
||||
t.string "available_type"
|
||||
t.string "available_type", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "nb_total_places"
|
||||
t.boolean "destroying", default: false
|
||||
t.boolean "lock", default: false
|
||||
t.boolean "destroying", default: false
|
||||
t.boolean "lock", default: false
|
||||
end
|
||||
|
||||
create_table "availability_tags", force: :cascade do |t|
|
||||
@ -105,7 +105,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "availability_tags", ["tag_id"], name: "index_availability_tags_on_tag_id", using: :btree
|
||||
|
||||
create_table "categories", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "name", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug"
|
||||
@ -114,7 +114,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "categories", ["slug"], name: "index_categories_on_slug", unique: true, using: :btree
|
||||
|
||||
create_table "components", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "name", limit: 255, null: false
|
||||
end
|
||||
|
||||
create_table "coupons", force: :cascade do |t|
|
||||
@ -132,7 +132,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
|
||||
create_table "credits", force: :cascade do |t|
|
||||
t.integer "creditable_id"
|
||||
t.string "creditable_type"
|
||||
t.string "creditable_type", limit: 255
|
||||
t.integer "plan_id"
|
||||
t.integer "hours"
|
||||
t.datetime "created_at"
|
||||
@ -173,7 +173,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "event_themes", ["slug"], name: "index_event_themes_on_slug", unique: true, using: :btree
|
||||
|
||||
create_table "events", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.string "title", limit: 255
|
||||
t.text "description"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
@ -211,10 +211,10 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "exports", ["user_id"], name: "index_exports_on_user_id", using: :btree
|
||||
|
||||
create_table "friendly_id_slugs", force: :cascade do |t|
|
||||
t.string "slug", null: false
|
||||
t.integer "sluggable_id", null: false
|
||||
t.string "slug", limit: 255, null: false
|
||||
t.integer "sluggable_id", null: false
|
||||
t.string "sluggable_type", limit: 50
|
||||
t.string "scope"
|
||||
t.string "scope", limit: 255
|
||||
t.datetime "created_at"
|
||||
end
|
||||
|
||||
@ -224,10 +224,10 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "friendly_id_slugs", ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type", using: :btree
|
||||
|
||||
create_table "groups", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "name", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug"
|
||||
t.string "slug", limit: 255
|
||||
t.boolean "disabled"
|
||||
end
|
||||
|
||||
@ -247,7 +247,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
|
||||
create_table "invoice_items", force: :cascade do |t|
|
||||
t.integer "invoice_id"
|
||||
t.string "stp_invoice_item_id"
|
||||
t.string "stp_invoice_item_id", limit: 255
|
||||
t.integer "amount"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
@ -261,16 +261,16 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
|
||||
create_table "invoices", force: :cascade do |t|
|
||||
t.integer "invoiced_id"
|
||||
t.string "invoiced_type"
|
||||
t.string "stp_invoice_id"
|
||||
t.string "invoiced_type", limit: 255
|
||||
t.string "stp_invoice_id", limit: 255
|
||||
t.integer "total"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "reference"
|
||||
t.string "avoir_mode"
|
||||
t.string "reference", limit: 255
|
||||
t.string "avoir_mode", limit: 255
|
||||
t.datetime "avoir_date"
|
||||
t.integer "invoice_id"
|
||||
t.string "type"
|
||||
t.string "type", limit: 255
|
||||
t.boolean "subscription_to_expire"
|
||||
t.text "description"
|
||||
t.integer "wallet_amount"
|
||||
@ -291,6 +291,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
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
|
||||
@ -298,17 +299,17 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
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.string "name", limit: 255, null: false
|
||||
t.text "description"
|
||||
end
|
||||
|
||||
create_table "machines", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "name", limit: 255, null: false
|
||||
t.text "description"
|
||||
t.text "spec"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug"
|
||||
t.string "slug", limit: 255
|
||||
t.boolean "disabled"
|
||||
end
|
||||
|
||||
@ -325,14 +326,14 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
create_table "notifications", force: :cascade do |t|
|
||||
t.integer "receiver_id"
|
||||
t.integer "attached_object_id"
|
||||
t.string "attached_object_type"
|
||||
t.string "attached_object_type", limit: 255
|
||||
t.integer "notification_type_id"
|
||||
t.boolean "is_read", default: false
|
||||
t.boolean "is_read", default: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "receiver_type"
|
||||
t.boolean "is_send", default: false
|
||||
t.jsonb "meta_data", default: {}
|
||||
t.boolean "is_send", default: false
|
||||
t.jsonb "meta_data", default: {}
|
||||
end
|
||||
|
||||
add_index "notifications", ["notification_type_id"], name: "index_notifications_on_notification_type_id", using: :btree
|
||||
@ -395,28 +396,26 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
t.string "name"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "profile_id"
|
||||
t.integer "invoicing_profile_id"
|
||||
end
|
||||
|
||||
add_index "organizations", ["invoicing_profile_id"], name: "index_organizations_on_invoicing_profile_id", using: :btree
|
||||
add_index "organizations", ["profile_id"], name: "index_organizations_on_profile_id", using: :btree
|
||||
|
||||
create_table "plans", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "name", limit: 255
|
||||
t.integer "amount"
|
||||
t.string "interval"
|
||||
t.string "interval", limit: 255
|
||||
t.integer "group_id"
|
||||
t.string "stp_plan_id"
|
||||
t.string "stp_plan_id", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "training_credit_nb", default: 0
|
||||
t.boolean "is_rolling", default: true
|
||||
t.integer "training_credit_nb", default: 0
|
||||
t.boolean "is_rolling", default: true
|
||||
t.text "description"
|
||||
t.string "type"
|
||||
t.string "base_name"
|
||||
t.integer "ui_weight", default: 0
|
||||
t.integer "interval_count", default: 1
|
||||
t.integer "ui_weight", default: 0
|
||||
t.integer "interval_count", default: 1
|
||||
t.string "slug"
|
||||
t.boolean "disabled"
|
||||
end
|
||||
@ -446,11 +445,11 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
|
||||
create_table "profiles", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.string "first_name", limit: 255
|
||||
t.string "last_name", limit: 255
|
||||
t.boolean "gender"
|
||||
t.date "birthday"
|
||||
t.string "phone"
|
||||
t.string "phone", limit: 255
|
||||
t.text "interest"
|
||||
t.text "software_mastered"
|
||||
t.datetime "created_at"
|
||||
@ -480,7 +479,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
t.integer "project_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "title"
|
||||
t.string "title", limit: 255
|
||||
t.integer "step_nb"
|
||||
end
|
||||
|
||||
@ -491,27 +490,27 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
t.integer "user_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.boolean "is_valid", default: false
|
||||
t.string "valid_token"
|
||||
t.boolean "is_valid", default: false
|
||||
t.string "valid_token", limit: 255
|
||||
end
|
||||
|
||||
add_index "project_users", ["project_id"], name: "index_project_users_on_project_id", using: :btree
|
||||
add_index "project_users", ["user_id"], name: "index_project_users_on_user_id", using: :btree
|
||||
|
||||
create_table "projects", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "name", limit: 255
|
||||
t.text "description"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "author_id"
|
||||
t.text "tags"
|
||||
t.integer "licence_id"
|
||||
t.string "state"
|
||||
t.string "slug"
|
||||
t.string "state", limit: 255
|
||||
t.string "slug", limit: 255
|
||||
t.datetime "published_at"
|
||||
end
|
||||
|
||||
add_index "projects", ["slug"], name: "index_projects_on_slug", unique: true, using: :btree
|
||||
add_index "projects", ["slug"], name: "index_projects_on_slug", using: :btree
|
||||
|
||||
create_table "projects_components", force: :cascade do |t|
|
||||
t.integer "project_id"
|
||||
@ -551,19 +550,19 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "reservable_id"
|
||||
t.string "reservable_type"
|
||||
t.string "stp_invoice_id"
|
||||
t.string "reservable_type", limit: 255
|
||||
t.string "stp_invoice_id", limit: 255
|
||||
t.integer "nb_reserve_places"
|
||||
end
|
||||
|
||||
add_index "reservations", ["reservable_type", "reservable_id"], name: "index_reservations_on_reservable_type_and_reservable_id", using: :btree
|
||||
add_index "reservations", ["reservable_id", "reservable_type"], name: "index_reservations_on_reservable_id_and_reservable_type", using: :btree
|
||||
add_index "reservations", ["stp_invoice_id"], name: "index_reservations_on_stp_invoice_id", using: :btree
|
||||
add_index "reservations", ["user_id"], name: "index_reservations_on_user_id", using: :btree
|
||||
|
||||
create_table "roles", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "name", limit: 255
|
||||
t.integer "resource_id"
|
||||
t.string "resource_type"
|
||||
t.string "resource_type", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@ -637,18 +636,18 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
|
||||
create_table "statistic_fields", force: :cascade do |t|
|
||||
t.integer "statistic_index_id"
|
||||
t.string "key"
|
||||
t.string "label"
|
||||
t.string "key", limit: 255
|
||||
t.string "label", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "data_type"
|
||||
t.string "data_type", limit: 255
|
||||
end
|
||||
|
||||
add_index "statistic_fields", ["statistic_index_id"], name: "index_statistic_fields_on_statistic_index_id", using: :btree
|
||||
|
||||
create_table "statistic_graphs", force: :cascade do |t|
|
||||
t.integer "statistic_index_id"
|
||||
t.string "chart_type"
|
||||
t.string "chart_type", limit: 255
|
||||
t.integer "limit"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
@ -657,17 +656,17 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "statistic_graphs", ["statistic_index_id"], name: "index_statistic_graphs_on_statistic_index_id", using: :btree
|
||||
|
||||
create_table "statistic_indices", force: :cascade do |t|
|
||||
t.string "es_type_key"
|
||||
t.string "label"
|
||||
t.string "es_type_key", limit: 255
|
||||
t.string "label", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.boolean "table", default: true
|
||||
t.boolean "ca", default: true
|
||||
t.boolean "table", default: true
|
||||
t.boolean "ca", default: true
|
||||
end
|
||||
|
||||
create_table "statistic_sub_types", force: :cascade do |t|
|
||||
t.string "key"
|
||||
t.string "label"
|
||||
t.string "key", limit: 255
|
||||
t.string "label", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@ -684,8 +683,8 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
|
||||
create_table "statistic_types", force: :cascade do |t|
|
||||
t.integer "statistic_index_id"
|
||||
t.string "key"
|
||||
t.string "label"
|
||||
t.string "key", limit: 255
|
||||
t.string "label", limit: 255
|
||||
t.boolean "graph"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
@ -703,7 +702,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
create_table "subscriptions", force: :cascade do |t|
|
||||
t.integer "plan_id"
|
||||
t.integer "user_id"
|
||||
t.string "stp_subscription_id"
|
||||
t.string "stp_subscription_id", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "expiration_date"
|
||||
@ -722,7 +721,7 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
|
||||
|
||||
create_table "themes", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "name", limit: 255, null: false
|
||||
end
|
||||
|
||||
create_table "tickets", force: :cascade do |t|
|
||||
@ -737,13 +736,13 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "tickets", ["reservation_id"], name: "index_tickets_on_reservation_id", using: :btree
|
||||
|
||||
create_table "trainings", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "name", limit: 255
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "nb_total_places"
|
||||
t.string "slug"
|
||||
t.string "slug", limit: 255
|
||||
t.text "description"
|
||||
t.boolean "public_page", default: true
|
||||
t.boolean "public_page", default: true
|
||||
t.boolean "disabled"
|
||||
end
|
||||
|
||||
@ -799,31 +798,31 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_index "user_trainings", ["user_id"], name: "index_user_trainings_on_user_id", using: :btree
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
t.string "reset_password_token"
|
||||
t.string "email", limit: 255, default: "", null: false
|
||||
t.string "encrypted_password", limit: 255, default: "", null: false
|
||||
t.string "reset_password_token", limit: 255
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.string "confirmation_token"
|
||||
t.string "current_sign_in_ip", limit: 255
|
||||
t.string "last_sign_in_ip", limit: 255
|
||||
t.string "confirmation_token", limit: 255
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "unconfirmed_email"
|
||||
t.integer "failed_attempts", default: 0, null: false
|
||||
t.string "unlock_token"
|
||||
t.string "unconfirmed_email", limit: 255
|
||||
t.integer "failed_attempts", default: 0, null: false
|
||||
t.string "unlock_token", limit: 255
|
||||
t.datetime "locked_at"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.boolean "is_allow_contact", default: true
|
||||
t.boolean "is_allow_contact", default: true
|
||||
t.integer "group_id"
|
||||
t.string "stp_customer_id"
|
||||
t.string "username"
|
||||
t.string "slug"
|
||||
t.boolean "is_active", default: true
|
||||
t.string "stp_customer_id", limit: 255
|
||||
t.string "username", limit: 255
|
||||
t.string "slug", limit: 255
|
||||
t.boolean "is_active", default: true
|
||||
t.string "provider"
|
||||
t.string "uid"
|
||||
t.string "auth_token"
|
||||
@ -903,7 +902,6 @@ ActiveRecord::Schema.define(version: 20190528140012) do
|
||||
add_foreign_key "o_auth2_mappings", "o_auth2_providers"
|
||||
add_foreign_key "open_api_calls_count_tracings", "open_api_clients"
|
||||
add_foreign_key "organizations", "invoicing_profiles"
|
||||
add_foreign_key "organizations", "profiles"
|
||||
add_foreign_key "prices", "groups"
|
||||
add_foreign_key "prices", "plans"
|
||||
add_foreign_key "projects_spaces", "projects"
|
||||
|
53
doc/postgresql_readme.md
Normal file
53
doc/postgresql_readme.md
Normal file
@ -0,0 +1,53 @@
|
||||
# Detailed informations about PostgreSQL usage in fab-manager
|
||||
|
||||
<a name="run-postgresql-cli"></a>
|
||||
## 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
|
||||
```
|
||||
|
||||
<a name="postgresql-limitations"></a>
|
||||
## 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.
|
||||
|
||||
|
||||
<a name="using-another-dbms"></a>
|
||||
## 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`.
|
7
test/fixtures/invoicing_profiles.yml
vendored
7
test/fixtures/invoicing_profiles.yml
vendored
@ -3,39 +3,46 @@ admin:
|
||||
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
|
||||
|
@ -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'
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user