mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-20 14:54:15 +01:00
Merge branch 'dev' for release 6.3.17
This commit is contained in:
commit
b05b295bda
10
CHANGELOG.md
10
CHANGELOG.md
@ -2,6 +2,16 @@
|
||||
|
||||
## Next release
|
||||
|
||||
## v6.3.17 2024 Avril 8
|
||||
|
||||
- improvement: add loader for create/delete availability slot
|
||||
- improvement: allow admin configure memeber's profile gender/birthday as required
|
||||
- improvement: add sp certificate for saml provider
|
||||
- Fix a bug: unable to update a space with a deleted machine
|
||||
- Fix a bug: unable to get invoice payment details if the account code is same for card/transfer payment method
|
||||
- Fix a bug: unable to show machine/training picture
|
||||
- updates translations
|
||||
|
||||
## v6.3.16 2024 March 11
|
||||
|
||||
- Fix a bug: set settlement by cash by default for local payment mean
|
||||
|
@ -108,7 +108,8 @@ class API::AuthProvidersController < API::APIController
|
||||
elsif params['auth_provider']['providable_type'] == SamlProvider.name
|
||||
params.require(:auth_provider)
|
||||
.permit(:id, :name, :providable_type,
|
||||
providable_attributes: [:id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url],
|
||||
providable_attributes: %i[id sp_entity_id idp_sso_service_url profile_url idp_cert_fingerprint idp_cert
|
||||
idp_slo_service_url authn_requests_signed want_assertions_signed sp_certificate sp_private_key],
|
||||
auth_provider_mappings_attributes: [:id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type,
|
||||
:_destroy, { transformation: [:type, :format, :true_value, :false_value,
|
||||
{ mapping: %i[from to] }] }])
|
||||
|
@ -118,7 +118,7 @@ export const ProviderForm: React.FC<ProviderFormProps> = ({ action, provider, on
|
||||
currentFormValues={output.providable_attributes as OpenIdConnectProvider}
|
||||
formState={formState}
|
||||
setValue={setValue} />}
|
||||
{providableType === 'SamlProvider' && <SamlForm register={register} strategyName={strategyName} formState={formState} />}
|
||||
{providableType === 'SamlProvider' && <SamlForm register={register} control={control} strategyName={strategyName} formState={formState} />}
|
||||
{providableType && providableType !== 'DatabaseProvider' && <DataMappingForm register={register}
|
||||
control={control}
|
||||
formState={formState}
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { FormInput } from '../form/form-input';
|
||||
import { UseFormRegister, FormState } from 'react-hook-form';
|
||||
import { FormSwitch } from '../form/form-switch';
|
||||
import { UseFormRegister, FormState, Control } from 'react-hook-form';
|
||||
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FabOutputCopy } from '../base/fab-output-copy';
|
||||
import ValidationLib from '../../lib/validation';
|
||||
|
||||
interface SamlFormProps<TFieldValues> {
|
||||
interface SamlFormProps<TFieldValues, TContext extends object> {
|
||||
register: UseFormRegister<TFieldValues>,
|
||||
control: Control<TFieldValues, TContext>,
|
||||
formState: FormState<TFieldValues>,
|
||||
strategyName?: string,
|
||||
}
|
||||
@ -14,7 +15,7 @@ interface SamlFormProps<TFieldValues> {
|
||||
/**
|
||||
* Partial form to fill the OAuth2 settings for a new/existing authentication provider.
|
||||
*/
|
||||
export const SamlForm = <TFieldValues extends FieldValues>({ register, strategyName, formState }: SamlFormProps<TFieldValues>) => {
|
||||
export const SamlForm = <TFieldValues extends FieldValues, TContext extends object>({ register, strategyName, formState, control }: SamlFormProps<TFieldValues, TContext>) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
/**
|
||||
@ -39,7 +40,7 @@ export const SamlForm = <TFieldValues extends FieldValues>({ register, strategyN
|
||||
placeholder="https://sso.example.net..."
|
||||
label={t('app.admin.authentication.saml_form.idp_sso_service_url')}
|
||||
tooltip={t('app.admin.authentication.saml_form.idp_sso_service_url_help')}
|
||||
rules={{ required: true, pattern: ValidationLib.urlRegex }}
|
||||
rules={{ required: true }}
|
||||
formState={formState} />
|
||||
<FormInput id="providable_attributes.idp_cert_fingerprint"
|
||||
register={register}
|
||||
@ -56,14 +57,29 @@ export const SamlForm = <TFieldValues extends FieldValues>({ register, strategyN
|
||||
placeholder="https://exemple.net/user..."
|
||||
label={t('app.admin.authentication.saml_form.profile_edition_url')}
|
||||
tooltip={t('app.admin.authentication.saml_form.profile_edition_url_help')}
|
||||
rules={{ required: true, pattern: ValidationLib.urlRegex }}
|
||||
rules={{ required: true }}
|
||||
formState={formState} />
|
||||
<FormInput id="providable_attributes.idp_slo_service_url"
|
||||
register={register}
|
||||
placeholder="https://sso.exemple.net..."
|
||||
label={t('app.admin.authentication.saml_form.idp_slo_service_url')}
|
||||
tooltip={t('app.admin.authentication.saml_form.idp_slo_service_url_help')}
|
||||
rules={{ pattern: ValidationLib.urlRegex }}
|
||||
formState={formState} />
|
||||
<FormSwitch id="providable_attributes.authn_requests_signed" control={control}
|
||||
formState={formState}
|
||||
label={t('app.admin.authentication.saml_form.authn_requests_signed')} />
|
||||
<FormSwitch id="providable_attributes.want_assertions_signed" control={control}
|
||||
formState={formState}
|
||||
label={t('app.admin.authentication.saml_form.want_assertions_signed')} />
|
||||
<FormInput id="providable_attributes.sp_certificate"
|
||||
register={register}
|
||||
placeholder="-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----"
|
||||
label={t('app.admin.authentication.saml_form.sp_certificate')}
|
||||
formState={formState} />
|
||||
<FormInput id="providable_attributes.sp_private_key"
|
||||
register={register}
|
||||
placeholder="-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----"
|
||||
label={t('app.admin.authentication.saml_form.sp_private_key')}
|
||||
formState={formState} />
|
||||
</div>
|
||||
);
|
||||
|
@ -49,9 +49,10 @@ const MachineCard: React.FC<MachineCardProps> = ({ user, machine, onShowMachine,
|
||||
if (!machine.machine_image_attributes?.attachment_url) {
|
||||
return <div className="machine-picture no-picture" />;
|
||||
}
|
||||
console.log(machine.machine_image_attributes.attachment_url);
|
||||
|
||||
return (
|
||||
<div className="machine-picture" style={{ backgroundImage: `url(${machine.machine_image_attributes.attachment_url}), url('/default-image.png')` }} onClick={handleShowMachine} />
|
||||
<div className="machine-picture" style={{ backgroundImage: `url("${machine.machine_image_attributes.attachment_url}"), url('/default-image.png')` }} onClick={handleShowMachine} />
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -93,7 +93,7 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
||||
});
|
||||
setValue('invoicing_profile_attributes.user_profile_custom_fields_attributes', userProfileCustomFields);
|
||||
}).catch(error => onError(error));
|
||||
SettingAPI.query(['phone_required', 'address_required', 'external_id'])
|
||||
SettingAPI.query(['phone_required', 'address_required', 'external_id', 'gender_required', 'birthday_required'])
|
||||
.then(settings => setFieldsSettings(settings))
|
||||
.catch(error => onError(error));
|
||||
}, []);
|
||||
@ -185,7 +185,7 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
||||
<div className="fields-group">
|
||||
<div className="personnal-data">
|
||||
<h4>{t('app.shared.user_profile_form.personal_data')}</h4>
|
||||
<GenderInput register={register} disabled={isDisabled} required tooltip={t('app.shared.user_profile_form.used_for_statistics')} />
|
||||
<GenderInput register={register} disabled={isDisabled} required={fieldsSettings.get('gender_required') === 'true'} tooltip={t('app.shared.user_profile_form.used_for_statistics')} />
|
||||
<div className="names">
|
||||
<FormInput id="profile_attributes.last_name"
|
||||
register={register}
|
||||
@ -205,7 +205,7 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
||||
register={register}
|
||||
label={t('app.shared.user_profile_form.date_of_birth')}
|
||||
disabled={isDisabled}
|
||||
rules={{ required: true }}
|
||||
rules={{ required: fieldsSettings.get('birthday_required') === 'true' }}
|
||||
formState={formState}
|
||||
type="date"
|
||||
nullable />
|
||||
|
@ -789,6 +789,8 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui
|
||||
// number of slots for this availability
|
||||
$scope.slots_nb = slots;
|
||||
|
||||
$scope.saving = false;
|
||||
|
||||
/**
|
||||
* Adds or removes the provided machine from the current slot
|
||||
* @param machine {Object}
|
||||
@ -867,9 +869,14 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui
|
||||
if ($scope.isOnlySubscriptions && $scope.selectedPlans.length > 0) {
|
||||
$scope.availability.plan_ids = $scope.selectedPlans.map(function (p) { return p.id; });
|
||||
}
|
||||
$scope.saving = true;
|
||||
return Availability.save(
|
||||
{ availability: $scope.availability },
|
||||
function (availability) { $uibModalInstance.close(availability); }
|
||||
function (availability) { $uibModalInstance.close(availability); },
|
||||
function (error) {
|
||||
console.error(error);
|
||||
$scope.saving = false;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
@ -1158,15 +1165,19 @@ Application.Controllers.controller('DeleteRecurrentAvailabilityController', ['$s
|
||||
// with recurrent slots: how many slots should we delete?
|
||||
$scope.deleteMode = 'single';
|
||||
|
||||
$scope.deleting = false;
|
||||
|
||||
/**
|
||||
* Confirmation callback
|
||||
*/
|
||||
$scope.ok = function () {
|
||||
const { id, start_at, end_at } = availabilityPromise;
|
||||
$scope.deleting = true;
|
||||
// the admin has confirmed, delete the slot
|
||||
Availability.delete(
|
||||
{ id, mode: $scope.deleteMode },
|
||||
function (res) {
|
||||
$scope.deleting = false;
|
||||
// delete success
|
||||
if (res.deleted > 1) {
|
||||
growl.success(_t(
|
||||
@ -1185,6 +1196,7 @@ Application.Controllers.controller('DeleteRecurrentAvailabilityController', ['$s
|
||||
});
|
||||
},
|
||||
function (res) {
|
||||
$scope.deleting = false;
|
||||
// not everything was deleted
|
||||
const { data } = res;
|
||||
if (data.total > 1) {
|
||||
|
@ -720,6 +720,12 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
|
||||
// is the address required in _member_form?
|
||||
$scope.addressRequired = (settingsPromise.address_required === 'true');
|
||||
|
||||
// is the gender number required in _member_form?
|
||||
$scope.genderRequired = (settingsPromise.gender_required === 'true');
|
||||
|
||||
// is the birthday required in _member_form?
|
||||
$scope.birthdayRequired = (settingsPromise.birthday_required === 'true');
|
||||
|
||||
// is user validation required
|
||||
$scope.enableUserValidationRequired = (settingsPromise.user_validation_required === 'true');
|
||||
|
||||
@ -1060,6 +1066,12 @@ Application.Controllers.controller('NewMemberController', ['$scope', '$state', '
|
||||
// is the address required to sign-up?
|
||||
$scope.addressRequired = (settingsPromise.address_required === 'true');
|
||||
|
||||
// is the gender number required in _member_form?
|
||||
$scope.genderRequired = (settingsPromise.gender_required === 'true');
|
||||
|
||||
// is the birthday required in _member_form?
|
||||
$scope.birthdayRequired = (settingsPromise.birthday_required === 'true');
|
||||
|
||||
// Default member's profile parameters
|
||||
$scope.user = {
|
||||
plan_interval: '',
|
||||
@ -1205,6 +1217,12 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A
|
||||
// is the address required in _admin_form?
|
||||
$scope.addressRequired = (settingsPromise.address_required === 'true');
|
||||
|
||||
// is the gender number required in _admin_form?
|
||||
$scope.genderRequired = (settingsPromise.gender_required === 'true');
|
||||
|
||||
// is the birthday required in _admin_form?
|
||||
$scope.birthdayRequired = (settingsPromise.birthday_required === 'true');
|
||||
|
||||
// all available groups
|
||||
$scope.groups = groupsPromise;
|
||||
|
||||
@ -1276,6 +1294,12 @@ Application.Controllers.controller('NewManagerController', ['$state', '$scope',
|
||||
// is the address required in _admin_form?
|
||||
$scope.addressRequired = (settingsPromise.address_required === 'true');
|
||||
|
||||
// is the gender number required in _admin_form?
|
||||
$scope.genderRequired = (settingsPromise.gender_required === 'true');
|
||||
|
||||
// is the birthday required in _admin_form?
|
||||
$scope.birthdayRequired = (settingsPromise.birthday_required === 'true');
|
||||
|
||||
// list of all groups
|
||||
$scope.groups = groupsPromise.filter(function (g) { return !g.disabled; });
|
||||
|
||||
|
@ -103,6 +103,12 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
// is the address required to sign-up?
|
||||
$scope.addressRequired = (settingsPromise.address_required === 'true');
|
||||
|
||||
// is the gender required to sign-up?
|
||||
$scope.genderRequired = (settingsPromise.gender_required === 'true');
|
||||
|
||||
// is the birthday required to sign-up?
|
||||
$scope.birthdayRequired = (settingsPromise.birthday_required === 'true');
|
||||
|
||||
// reCaptcha v2 site key (or undefined)
|
||||
$scope.recaptchaSiteKey = settingsPromise.recaptcha_site_key;
|
||||
|
||||
|
@ -1096,15 +1096,19 @@ Application.Controllers.controller('DeleteRecurrentEventController', ['$scope',
|
||||
// with recurrent slots: how many slots should we delete?
|
||||
$scope.deleteMode = 'single';
|
||||
|
||||
$scope.deleting = false;
|
||||
|
||||
/**
|
||||
* Confirmation callback
|
||||
*/
|
||||
$scope.ok = function () {
|
||||
$scope.deleting = true;
|
||||
const { id, start_at, end_at } = eventPromise;
|
||||
// the admin has confirmed, delete the slot
|
||||
Event.delete(
|
||||
{ id, mode: $scope.deleteMode },
|
||||
function (res) {
|
||||
$scope.deleting = false;
|
||||
// delete success
|
||||
if (res.deleted > 1) {
|
||||
growl.success(_t(
|
||||
@ -1122,6 +1126,7 @@ Application.Controllers.controller('DeleteRecurrentEventController', ['$scope',
|
||||
});
|
||||
},
|
||||
function (res) {
|
||||
$scope.deleting = false;
|
||||
// not everything was deleted
|
||||
const { data } = res;
|
||||
if (data.total > 1) {
|
||||
|
@ -18,7 +18,7 @@ export default class ApiLib {
|
||||
...object,
|
||||
...attachmentAttributes.reduce((a, name) => { return { ...a, [name]: null }; }, {})
|
||||
}
|
||||
}, { dateWithTimezone: true });
|
||||
}, { dateWithTimezone: true, allowEmptyArrays: true });
|
||||
attachmentAttributes.forEach((attr) => {
|
||||
data.delete(`${name}[${attr}]`);
|
||||
if (Array.isArray(object[attr])) {
|
||||
|
@ -73,6 +73,10 @@ export interface SamlProvider {
|
||||
idp_cert: string,
|
||||
profile_url: string,
|
||||
idp_slo_service_url: string,
|
||||
sp_certificate: string,
|
||||
sp_private_key: string,
|
||||
authn_requests_signed: boolean,
|
||||
want_assertions_signed: boolean
|
||||
}
|
||||
|
||||
export interface MappingFields {
|
||||
|
@ -186,7 +186,9 @@ export const accountSettings = [
|
||||
'user_change_group',
|
||||
'user_validation_required',
|
||||
'user_validation_required_list',
|
||||
'family_account'
|
||||
'family_account',
|
||||
'gender_required',
|
||||
'birthday_required'
|
||||
] as const;
|
||||
|
||||
export const analyticsSettings = [
|
||||
|
@ -127,7 +127,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre', 'phone_required', 'address_required']" }).$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre', 'phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }],
|
||||
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }],
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
cguFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'cgu-file' }).$promise; }],
|
||||
@ -174,7 +174,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
groups: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }]
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.dashboard.supporting_document_files', {
|
||||
@ -1049,7 +1049,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }]
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.members_import', {
|
||||
@ -1090,7 +1090,7 @@ angular.module('application.router', ['ui.router'])
|
||||
walletPromise: ['Wallet', '$transition$', function (Wallet, $transition$) { return Wallet.getWalletByUser({ user_id: $transition$.params().id }).$promise; }],
|
||||
transactionsPromise: ['Wallet', 'walletPromise', function (Wallet, walletPromise) { return Wallet.transactions({ id: walletPromise.id }).$promise; }],
|
||||
tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'user_validation_required']" }).$promise; }]
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required', 'user_validation_required']" }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.admins_new', {
|
||||
@ -1102,7 +1102,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }],
|
||||
groupsPromise: ['Group', function (Group) { return Group.query({ disabled: false }).$promise; }]
|
||||
}
|
||||
})
|
||||
@ -1117,7 +1117,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }]
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -1200,7 +1200,7 @@ angular.module('application.router', ['ui.router'])
|
||||
"'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key', 'user_validation_required', " +
|
||||
"'user_validation_required_list', 'machines_module', 'user_change_group', " +
|
||||
"'store_module', 'machine_reservation_deadline', 'training_reservation_deadline', 'event_reservation_deadline', " +
|
||||
"'space_reservation_deadline', 'reservation_context_feature']"
|
||||
"'space_reservation_deadline', 'reservation_context_feature', 'gender_required', 'birthday_required']"
|
||||
}).$promise;
|
||||
}],
|
||||
privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }],
|
||||
|
@ -21,6 +21,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-info" ng-click="ok()" translate>{{ 'app.shared.buttons.delete' }}</button>
|
||||
<button class="btn btn-info" ng-class="{'btn-loading': deleting}" ng-click="ok()" ng-disabled="deleting" translate>{{ 'app.shared.buttons.delete' }}</button>
|
||||
<button class="btn btn-default" ng-click="cancel()" translate>{{ 'app.shared.buttons.cancel' }}</button>
|
||||
</div>
|
||||
|
@ -252,6 +252,6 @@
|
||||
</div>
|
||||
<div class="modal-footer" ng-show="step === 6">
|
||||
<button class="fab-button is-info" ng-click="previous()" translate>{{ 'app.admin.calendar.previous' }}</button>
|
||||
<button class="fab-button is-secondary" ng-click="ok()" translate>{{ 'app.shared.buttons.confirm' }}</button>
|
||||
<button class="fab-button is-secondary" ng-class="{'btn-loading': saving}" ng-disabled="saving" ng-click="ok()" translate>{{ 'app.shared.buttons.confirm' }}</button>
|
||||
<button class="fab-button" ng-click="cancel()" translate>{{ 'app.shared.buttons.cancel' }}</button>
|
||||
</div>
|
||||
|
@ -110,6 +110,32 @@
|
||||
<span class="font-sbold" translate>{{ 'app.admin.settings.account.customize_account_settings' }}</span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<h3 class="m-l" translate>{{ 'app.admin.settings.gender' }}</h3>
|
||||
<p class="alert alert-warning m-h-md" translate>
|
||||
{{ 'app.admin.settings.gender_required_info' }}
|
||||
</p>
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<boolean-setting name="'gender_required'"
|
||||
label="'app.admin.settings.gender_is_required' | translate"
|
||||
on-success="onSuccess"
|
||||
on-error="onError">
|
||||
</boolean-setting>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3 class="m-l" translate>{{ 'app.admin.settings.birthday' }}</h3>
|
||||
<p class="alert alert-warning m-h-md" translate>
|
||||
{{ 'app.admin.settings.birthday_required_info' }}
|
||||
</p>
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<boolean-setting name="'birthday_required'"
|
||||
label="'app.admin.settings.birthday_is_required' | translate"
|
||||
on-success="onSuccess"
|
||||
on-error="onError">
|
||||
</boolean-setting>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3 class="m-l" translate>{{ 'app.admin.settings.phone' }}</h3>
|
||||
<p class="alert alert-warning m-h-md" translate>
|
||||
|
@ -22,6 +22,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-info" ng-click="ok()" translate>{{ 'app.shared.buttons.delete' }}</button>
|
||||
<button class="btn btn-info" ng-class="{'btn-loading': deleting}" ng-click="ok()" ng-disabled="deleting" translate>{{ 'app.shared.buttons.delete' }}</button>
|
||||
<button class="btn btn-default" ng-click="cancel()" translate>{{ 'app.shared.buttons.cancel' }}</button>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<h4 class="text-sm m-t-sm" translate>{{ 'app.public.home.latest_documented_projects' }}</h4>
|
||||
|
||||
<uib-carousel interval="5000" disable-animation="true" active="activeSlide">
|
||||
<uib-slide class="h480 cover r" ng-repeat="p in lastProjects track by $index" index="$index" style="background-image:url({{p.project_image}});">
|
||||
<uib-slide class="h480 cover r" ng-repeat="p in lastProjects track by $index" index="$index" style="background-image:url('{{p.project_image}}');">
|
||||
<div class="carousel-caption">
|
||||
<h1 class="title"><a ui-sref="app.public.projects_show({id:p.slug})">{{p.name}}</a></h1>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
name="admin[statistic_profile_attributes][gender]"
|
||||
ng-model="admin.statistic_profile_attributes.gender"
|
||||
ng-value="true"
|
||||
required/>
|
||||
ng-required="genderRequired"/>
|
||||
<i class="fa fa-male m-l-sm"></i> {{ 'app.admin.admins_new.man' | translate }}
|
||||
</label>
|
||||
<label class="checkbox-inline btn btn-default">
|
||||
@ -16,7 +16,7 @@
|
||||
ng-value="false"/>
|
||||
<i class="fa fa-female m-l-sm"></i> {{ 'app.admin.admins_new.woman' | translate }}
|
||||
</label>
|
||||
<span class="exponent m-l-xs help-cursor"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span ng-show="genderRequired" class="exponent m-l-xs help-cursor"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': adminForm['admin[username]'].$dirty && adminForm['admin[username]'].$invalid}">
|
||||
@ -76,7 +76,9 @@
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': adminForm['admin[statistic_profile_attributes][birthday]'].$dirty && adminForm['admin[statistic_profile_attributes][birthday]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-calendar-o"></i> </span>
|
||||
<span class="input-group-addon"><i class="fa fa-calendar-o"></i>
|
||||
<span ng-show="birthdayRequired" class="exponent m-l-xs help-cursor"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
</span>
|
||||
<input type="text"
|
||||
id="user_birthday"
|
||||
class="form-control"
|
||||
@ -86,6 +88,7 @@
|
||||
is-open="datePicker.opened"
|
||||
placeholder="{{ 'app.admin.admins_new.birth_date' | translate }}"
|
||||
ng-click="openDatePicker($event)"
|
||||
ng-required="birthdayRequired"
|
||||
/>
|
||||
<input type="hidden"
|
||||
name="admin[statistic_profile_attributes][birthday]"
|
||||
|
@ -6,7 +6,7 @@
|
||||
name="manager[statistic_profile_attributes][gender]"
|
||||
ng-model="manager.statistic_profile_attributes.gender"
|
||||
ng-value="true"
|
||||
required/>
|
||||
ng-required="genderRequired"/>
|
||||
<i class="fa fa-male m-l-sm"></i> {{ 'app.admin.manager_new.man' | translate }}
|
||||
</label>
|
||||
<label class="checkbox-inline btn btn-default">
|
||||
@ -16,7 +16,7 @@
|
||||
ng-value="false"/>
|
||||
<i class="fa fa-female m-l-sm"></i> {{ 'app.admin.manager_new.woman' | translate }}
|
||||
</label>
|
||||
<span class="exponent m-l-xs help-cursor"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span ng-show="genderRequired" class="exponent m-l-xs help-cursor"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': managerForm['manager[username]'].$dirty && managerForm['manager[username]'].$invalid}">
|
||||
@ -76,7 +76,9 @@
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': managerForm['manager[statistic_profile_attributes][birthday]'].$dirty && managerForm['manager[statistic_profile_attributes][birthday]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-calendar-o"></i> </span>
|
||||
<span class="input-group-addon"><i class="fa fa-calendar-o"></i>
|
||||
<span ng-show="birthdayRequired" class="exponent m-l-xs help-cursor"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
</span>
|
||||
<input type="text"
|
||||
id="user_birthday"
|
||||
class="form-control"
|
||||
|
@ -15,7 +15,7 @@
|
||||
name="gender"
|
||||
ng-model="user.statistic_profile_attributes.gender"
|
||||
value="true"
|
||||
required/> {{ 'app.public.common.man' | translate }}
|
||||
ng-required="genderRequired"/> {{ 'app.public.common.man' | translate }}
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="radio"
|
||||
@ -27,7 +27,7 @@
|
||||
<span class="trigger"><i class="fa fa-question-circle"></i></span>
|
||||
<div class="content" translate="">{{ 'app.public.common.used_for_statistics' }}</div>
|
||||
</div>
|
||||
<span class="exponent m-l-xs"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span ng-show="genderRequired" class="exponent m-l-xs"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span class="help-block" ng-show="signupForm.gender.$dirty && signupForm.gender.$error.required" translate>{{ 'app.public.common.gender_is_required'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -222,9 +222,9 @@
|
||||
is-open="datePicker.opened"
|
||||
placeholder="{{ 'app.public.common.birth_date' | translate }}"
|
||||
ng-click="openDatePicker($event)"
|
||||
required/>
|
||||
ng-required="birthdayRequired"/>
|
||||
</div>
|
||||
<span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span ng-show="birthdayRequired" class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span class="help-block" ng-show="signupForm.birthday.$dirty && signupForm.birthday.$error.required" translate>{{ 'app.public.common.birth_date_is_required' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,7 +52,7 @@
|
||||
<div class="panel-heading picture" ng-if="!space.space_image_attributes" ng-click="showSpace(space)">
|
||||
<img src="data:image/png;base64," data-src="holder.js/100%x100%/text:/font:'Font Awesome 5 Free'/icon" bs-holder class="img-responsive">
|
||||
</div>
|
||||
<div class="panel-heading picture" style="background-image:url({{space.space_image_attributes.attachment_url}})" ng-if="space.space_image_attributes" ng-click="showSpace(space)">
|
||||
<div class="panel-heading picture" style="background-image:url('{{space.space_image_attributes.attachment_url}}')" ng-if="space.space_image_attributes" ng-click="showSpace(space)">
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h1 class="text-center m-b">{{space.name}}</h1>
|
||||
|
@ -25,7 +25,7 @@
|
||||
<div class="panel-heading picture" ng-if="!training.training_image_attributes" ng-click="showTraining(training)">
|
||||
<img src="data:image/png;base64," data-src="holder.js/100%x100%/text:/font:'Font Awesome 5 Free'/icon" bs-holder class="img-responsive">
|
||||
</div>
|
||||
<div class="panel-heading picture" style="background-image:url({{training.training_image_attributes.attachment_url}})" ng-if="training.training_image_attributes" ng-click="showTraining(training)">
|
||||
<div class="panel-heading picture" style="background-image:url('{{training.training_image_attributes.attachment_url}}')" ng-if="training.training_image_attributes" ng-click="showTraining(training)">
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h1 class="m-b text-center">{{training.name}}</h1>
|
||||
|
@ -31,7 +31,7 @@ module ExcelHelper
|
||||
user&.profile&.full_name || t('export.deleted_user'),
|
||||
user&.email || '',
|
||||
user&.profile&.phone || '',
|
||||
t("export.#{hit['_source']['gender']}"),
|
||||
hit['_source']['gender'].present? ? t("export.#{hit['_source']['gender']}") : '',
|
||||
hit['_source']['age'],
|
||||
subtype.nil? ? '' : subtype.label
|
||||
]
|
||||
|
@ -208,6 +208,8 @@ module SettingsHelper
|
||||
project_categories_filter_placeholder
|
||||
project_categories_wording
|
||||
reservation_context_feature
|
||||
gender_required
|
||||
birthday_required
|
||||
].freeze
|
||||
end
|
||||
# rubocop:enable Metrics/ModuleLength
|
||||
|
@ -31,6 +31,8 @@ class StatisticProfile < ApplicationRecord
|
||||
validate :check_birthday_in_past
|
||||
|
||||
def str_gender
|
||||
return '' if gender.blank?
|
||||
|
||||
gender ? 'male' : 'female'
|
||||
end
|
||||
|
||||
|
@ -115,8 +115,10 @@ class User < ApplicationRecord
|
||||
end
|
||||
|
||||
def need_completion?
|
||||
statistic_profile.gender.nil? || profile.first_name.blank? || profile.last_name.blank? || username.blank? ||
|
||||
email.blank? || encrypted_password.blank? || group_id.nil? || statistic_profile.birthday.blank? ||
|
||||
(Setting.get('gender_required') && statistic_profile.gender.blank?) ||
|
||||
profile.first_name.blank? || profile.last_name.blank? || username.blank? ||
|
||||
email.blank? || encrypted_password.blank? || group_id.nil? ||
|
||||
(Setting.get('birthday_required') && statistic_profile.birthday.blank?) ||
|
||||
(Setting.get('phone_required') && profile.phone.blank?) ||
|
||||
(Setting.get('address_required') && invoicing_profile&.address&.address&.blank?)
|
||||
end
|
||||
|
@ -47,7 +47,8 @@ class SettingPolicy < ApplicationPolicy
|
||||
machines_banner_cta_url trainings_banner_active trainings_banner_text trainings_banner_cta_active trainings_banner_cta_label
|
||||
trainings_banner_cta_url events_banner_active events_banner_text events_banner_cta_active events_banner_cta_label
|
||||
events_banner_cta_url projects_list_member_filter_presence projects_list_date_filters_presence advanced_accounting
|
||||
project_categories_filter_placeholder project_categories_wording reservation_context_feature family_account child_validation_required]
|
||||
project_categories_filter_placeholder project_categories_wording reservation_context_feature family_account child_validation_required
|
||||
gender_required birthday_required]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -6,7 +6,8 @@ json.partial! 'api/auth_providers/auth_provider', auth_provider: @provider
|
||||
|
||||
if @provider.providable_type == OAuth2Provider.name
|
||||
json.providable_attributes do
|
||||
json.extract! @provider.providable, :id, :base_url, :token_endpoint, :authorization_endpoint, :profile_url, :client_id, :client_secret, :scopes
|
||||
json.extract! @provider.providable, :id, :base_url, :token_endpoint, :authorization_endpoint, :profile_url, :client_id, :client_secret,
|
||||
:scopes
|
||||
end
|
||||
end
|
||||
|
||||
@ -22,6 +23,7 @@ end
|
||||
|
||||
if @provider.providable_type == SamlProvider.name
|
||||
json.providable_attributes do
|
||||
json.extract! @provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url
|
||||
json.extract! @provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url,
|
||||
:authn_requests_signed, :want_assertions_signed, :sp_certificate, :sp_private_key
|
||||
end
|
||||
end
|
||||
|
@ -23,6 +23,7 @@ end
|
||||
|
||||
if provider.providable_type == 'SamlProvider'
|
||||
json.providable_attributes do
|
||||
json.extract! provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url
|
||||
json.extract! provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url,
|
||||
:authn_requests_signed, :want_assertions_signed, :sp_certificate, :sp_private_key
|
||||
end
|
||||
end
|
||||
|
@ -49,7 +49,7 @@ wb.add_worksheet(name: ExcelService.name_safe(t('export_members.members'))) do |
|
||||
member.email,
|
||||
member.is_allow_newsletter,
|
||||
member.last_sign_in_at&.to_date,
|
||||
member.statistic_profile.gender ? t('export_members.man') : t('export_members.woman'),
|
||||
member.statistic_profile.gender.present? ? (member.statistic_profile.gender ? t('export_members.man') : t('export_members.woman')) : '',
|
||||
member.statistic_profile.age,
|
||||
member.invoicing_profile&.address&.address || '',
|
||||
member.profile.phone,
|
||||
|
@ -11,7 +11,7 @@ json.lines @lines do |line|
|
||||
json.url download_open_api_v1_invoice_path(line.invoice)
|
||||
json.payment_method line.invoice_payment_method
|
||||
if @codes.values.include?(line.account_code) # if this is a 'payment' line
|
||||
mean = @codes.select { |_key, value| value == line.account_code }
|
||||
mean = @codes.select { |_key, value| value == line.account_code && _key == line.invoice_payment_method.to_sym }
|
||||
json.payment_details line.invoice.payment_details(mean.keys[0])
|
||||
end
|
||||
end
|
||||
|
@ -253,6 +253,12 @@ Devise.setup do |config|
|
||||
idp_slo_service_url: active_provider.providable.idp_slo_service_url,
|
||||
idp_cert: active_provider.providable.idp_cert,
|
||||
idp_cert_fingerprint: active_provider.providable.idp_cert_fingerprint,
|
||||
certificate: active_provider.providable.sp_certificate,
|
||||
private_key: active_provider.providable.sp_private_key,
|
||||
security: OneLogin::RubySaml::Settings::DEFAULTS[:security].merge({
|
||||
authn_requests_signed: active_provider.providable.authn_requests_signed,
|
||||
want_assertions_signed: active_provider.providable.want_assertions_signed
|
||||
}),
|
||||
strategy_class: OmniAuth::Strategies::SsoSamlProvider
|
||||
end
|
||||
end
|
||||
|
@ -1571,6 +1571,10 @@ de:
|
||||
profile_edition_url_help: "The URL of the page where the user can edit his profile."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Name"
|
||||
authentication_type: "Authentifizierungsart"
|
||||
@ -1787,6 +1791,8 @@ de:
|
||||
fab_analytics: "Fab-Analytics"
|
||||
phone_required: "Telefonummer erforderlich"
|
||||
address_required: "Adresse erforderlich"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "Tracking-ID"
|
||||
facebook_app_id: "Facebook App-ID"
|
||||
twitter_analytics: "Twitter Analytics-Konto"
|
||||
@ -1839,6 +1845,12 @@ de:
|
||||
address: "Adresse"
|
||||
address_required_info_html: "Sie können festlegen, ob eine Adresse für die Neuregistrierung eines Benutzers erforderlich sein soll.<br/><strong>Bitte beachten Sie</strong> dass in Abhängigkeit von Landesvorschriften Adressen für die Gültigkeit der Rechnungen erforderlich sein können."
|
||||
address_is_required: "Adresse ist erforderlich"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "External identifier"
|
||||
external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself."
|
||||
enable_external_id: "Enable the external ID"
|
||||
|
@ -1571,6 +1571,10 @@ en:
|
||||
profile_edition_url_help: "The URL of the page where the user can edit his profile."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Name"
|
||||
authentication_type: "Authentication type"
|
||||
@ -1787,6 +1791,8 @@ en:
|
||||
fab_analytics: "Fab Analytics"
|
||||
phone_required: "phone required"
|
||||
address_required: "address required"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "tracking ID"
|
||||
facebook_app_id: "Facebook App ID"
|
||||
twitter_analytics: "Twitter analytics account"
|
||||
@ -1839,6 +1845,12 @@ en:
|
||||
address: "Address"
|
||||
address_required_info_html: "You can define if the address should be required to register a new user on Fab-manager.<br/><strong>Please note</strong> that, depending on your country, the regulations may requires addresses for the invoices to be valid."
|
||||
address_is_required: "Address is required"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "External identifier"
|
||||
external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself."
|
||||
enable_external_id: "Enable the external ID"
|
||||
|
@ -1571,6 +1571,10 @@ es-MX:
|
||||
profile_edition_url_help: "The URL of the page where the user can edit his profile."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Nombre"
|
||||
authentication_type: "Tipo de autenticación"
|
||||
@ -1787,6 +1791,8 @@ es-MX:
|
||||
fab_analytics: "Fab Analytics"
|
||||
phone_required: "teléfono requerido"
|
||||
address_required: "dirección requerida"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "ID de seguimiento"
|
||||
facebook_app_id: "ID de aplicación de Facebook"
|
||||
twitter_analytics: "Cuenta analítica de Twitter"
|
||||
@ -1839,6 +1845,12 @@ es-MX:
|
||||
address: "Dirección"
|
||||
address_required_info_html: "Puede definir si la dirección debe ser necesaria para registrar un nuevo usuario en Fab-manager.<br/><strong>Tenga en cuenta</strong> que, dependiendo de su país, la normativa puede exigir direcciones para que los recibos sean válidos."
|
||||
address_is_required: "Dirección requerida"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "Identificador externo"
|
||||
external_id_info_html: "Puede establecer un identificador externo para sus usuarios, que no podrá ser modificado por el propio usuario."
|
||||
enable_external_id: "Activar el ID externo"
|
||||
|
@ -1571,6 +1571,10 @@ es:
|
||||
profile_edition_url_help: "The URL of the page where the user can edit his profile."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Nombre"
|
||||
authentication_type: "Tipo de autenticación"
|
||||
@ -1787,6 +1791,8 @@ es:
|
||||
fab_analytics: "Fab Analytics"
|
||||
phone_required: "teléfono requerido"
|
||||
address_required: "dirección requerida"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "ID de seguimiento"
|
||||
facebook_app_id: "ID de aplicación de Facebook"
|
||||
twitter_analytics: "Cuenta analítica de Twitter"
|
||||
@ -1839,6 +1845,12 @@ es:
|
||||
address: "Dirección"
|
||||
address_required_info_html: "Puede definir si la dirección debe ser necesaria para registrar un nuevo usuario en Fab-manager.<br/><strong>Tenga en cuenta</strong> que, dependiendo de su país, la normativa puede exigir direcciones para que las facturas sean válidas."
|
||||
address_is_required: "Dirección requerida"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "Identificador externo"
|
||||
external_id_info_html: "Puede establecer un identificador externo para sus usuarios, que no podrá ser modificado por el propio usuario."
|
||||
enable_external_id: "Activar el ID externo"
|
||||
|
@ -1383,7 +1383,7 @@ fr:
|
||||
to_credit: 'Créditer'
|
||||
cannot_credit_own_wallet: "Vous ne pouvez pas créditer votre propre porte-monnaie. Veuillez demander à un autre gestionnaire ou à un administrateur de créditer votre porte-monnaie."
|
||||
cannot_extend_own_subscription: "Vous ne pouvez pas prolonger votre propre abonnement. Veuillez demander à un autre gestionnaire ou à un administrateur de prolonger votre abonnement."
|
||||
update_success: "Le profile du membre a bien été mis à jour"
|
||||
update_success: "Le profil du membre a bien été mis à jour"
|
||||
my_documents: "Mes documents"
|
||||
save: "Enregistrer"
|
||||
confirm: "Valider"
|
||||
@ -1571,6 +1571,10 @@ fr:
|
||||
profile_edition_url_help: "L'URL de la page où l'utilisateur peut modifier son profil."
|
||||
idp_slo_service_url: "URL de demande de déconnexion"
|
||||
idp_slo_service_url_help: "L'URL à laquelle la requête d'authentification doit être envoyée. Cela serait sur le fournisseur d'identité."
|
||||
authn_requests_signed: "Demandes d'authentification signées"
|
||||
want_assertions_signed: "Exiger des Assertions signées"
|
||||
sp_certificate: "Certificat du SP"
|
||||
sp_private_key: "Clé privée du SP"
|
||||
provider_form:
|
||||
name: "Nom"
|
||||
authentication_type: "Type d'authentification"
|
||||
@ -1787,6 +1791,8 @@ fr:
|
||||
fab_analytics: "Fab Analytics"
|
||||
phone_required: "téléphone requis"
|
||||
address_required: "adresse requise"
|
||||
gender_required: "genre requis"
|
||||
birthday_required: "date de naissance requise"
|
||||
tracking_id: "l'ID de suivi"
|
||||
facebook_app_id: "l'App ID Facebook"
|
||||
twitter_analytics: "compte Twitter analytics"
|
||||
@ -1839,6 +1845,12 @@ fr:
|
||||
address: "Adresse"
|
||||
address_required_info_html: "Vous pouvez définir si l'adresse doit être requise, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager.<br/><strong>Veuillez noter</strong> que, selon votre pays, la réglementation peut exiger des adresses pour que les factures soient valides."
|
||||
address_is_required: "Adresse requise"
|
||||
gender: "Genre"
|
||||
gender_is_required: "Genre requis"
|
||||
gender_required_info: "Vous pouvez définir si le genre doit être requis, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager."
|
||||
birthday: "Date de naissance"
|
||||
birthday_is_required: "Date de naissance requise"
|
||||
birthday_required_info: "Vous pouvez définir si la date de naissance doit être requis, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager."
|
||||
external_id: "Identifiant externe"
|
||||
external_id_info_html: "Vous pouvez configurer un identifiant externe pour vos utilisateurs, qui ne pourra pas être modifié par l'utilisateur lui-même."
|
||||
enable_external_id: "Activer l'identifiant externe"
|
||||
|
@ -1571,6 +1571,10 @@ it:
|
||||
profile_edition_url_help: "The URL of the page where the user can edit his profile."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Nome"
|
||||
authentication_type: "Tipo di autenticazione"
|
||||
@ -1787,6 +1791,8 @@ it:
|
||||
fab_analytics: "Fab Analytics"
|
||||
phone_required: "telefono richiesto"
|
||||
address_required: "indirizzo richiesto"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "tracking ID"
|
||||
facebook_app_id: "Facebook App ID"
|
||||
twitter_analytics: "Account analytics Twitter"
|
||||
@ -1839,6 +1845,12 @@ it:
|
||||
address: "Indirizzo"
|
||||
address_required_info_html: "È possibile definire se l'indirizzo deve essere richiesto per registrare un nuovo utente su Fab-manager.<br/><strong>Si prega di notare</strong> che, a seconda del tuo paese, la normativa potrebbe richiedere indirizzi per la validità delle fatture."
|
||||
address_is_required: "L'indirizzo è obbligatorio"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "Identificatore esterno"
|
||||
external_id_info_html: "È possibile impostare un identificatore esterno per i propri utenti, che non può essere modificato dall'utente stesso."
|
||||
enable_external_id: "Abilita l'ID esterno"
|
||||
|
@ -1571,6 +1571,10 @@
|
||||
profile_edition_url_help: "The URL of the page where the user can edit his profile."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Name"
|
||||
authentication_type: "Authentication type"
|
||||
@ -1787,6 +1791,8 @@
|
||||
fab_analytics: "Fab Analytics"
|
||||
phone_required: "phone required"
|
||||
address_required: "address required"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "tracking ID"
|
||||
facebook_app_id: "Facebook App ID"
|
||||
twitter_analytics: "Twitter analytics account"
|
||||
@ -1839,6 +1845,12 @@
|
||||
address: "Address"
|
||||
address_required_info_html: "You can define if the address should be required to register a new user on Fab-manager.<br/><strong>Please note</strong> that, depending on your country, the regulations may requires addresses for the invoices to be valid."
|
||||
address_is_required: "Adresse er påkrevd"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "External identifier"
|
||||
external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself."
|
||||
enable_external_id: "Enable the external ID"
|
||||
|
@ -1571,6 +1571,10 @@ pt:
|
||||
profile_edition_url_help: "The URL of the page where the user can edit his profile."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Nome"
|
||||
authentication_type: "Tipo de autenticação"
|
||||
@ -1787,6 +1791,8 @@ pt:
|
||||
fab_analytics: "Fab Analytics"
|
||||
phone_required: "telefone é obrigatório"
|
||||
address_required: "o endereço é obrigatório"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "tracking ID"
|
||||
facebook_app_id: "ID de Utilizador do Facebook"
|
||||
twitter_analytics: "Analisador de conta Twitter"
|
||||
@ -1839,6 +1845,12 @@ pt:
|
||||
address: "Endereço"
|
||||
address_required_info_html: "Você pode definir se o endereço deve ser necessário para registrar um novo usuário no Fab-manager.<br/><strong>Por favor, note</strong> que, dependendo do seu país, as regulamentações podem exigir endereços para que as faturas sejam válidas."
|
||||
address_is_required: "Endereço é obrigatório"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "External identifier"
|
||||
external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself."
|
||||
enable_external_id: "Enable the external ID"
|
||||
|
@ -1571,6 +1571,10 @@ sv:
|
||||
profile_edition_url_help: "URL till sidan där användaren kan redigera sin profil."
|
||||
idp_slo_service_url: "Single logout request URL"
|
||||
idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider."
|
||||
authn_requests_signed: "Authentification requests signed"
|
||||
want_assertions_signed: "Want assertions signed"
|
||||
sp_certificate: "Service provider certificate"
|
||||
sp_private_key: "Service provider private key"
|
||||
provider_form:
|
||||
name: "Namn"
|
||||
authentication_type: "Autentiseringstyp"
|
||||
@ -1787,6 +1791,8 @@ sv:
|
||||
fab_analytics: "Fab Analys"
|
||||
phone_required: "telefon krävs"
|
||||
address_required: "adress krävs"
|
||||
gender_required: "gender required"
|
||||
birthday_required: "date of birth required"
|
||||
tracking_id: "spårnings-ID"
|
||||
facebook_app_id: "ID för Facebook-app"
|
||||
twitter_analytics: "Twitter analytics-konto"
|
||||
@ -1839,6 +1845,12 @@ sv:
|
||||
address: "Adress"
|
||||
address_required_info_html: "Du kan definiera om adress krävs för att registrera en ny användare. <br/><strong>OBS:</strong> beroende på landstillhörighet kan lagen kräva att giltiga fakturor har en faktureringsadress."
|
||||
address_is_required: "Adress måste fyllas i"
|
||||
gender: "Gender"
|
||||
gender_is_required: "Gender required"
|
||||
gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager."
|
||||
birthday: "Date of birth"
|
||||
birthday_is_required: "Date of birth required"
|
||||
birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager."
|
||||
external_id: "Extern identifierare"
|
||||
external_id_info_html: "Du kan ställa in en extern identifierare för dina användare, som inte kan ändras av användaren själv."
|
||||
enable_external_id: "Aktivera externt ID"
|
||||
|
@ -1571,6 +1571,10 @@ zu:
|
||||
profile_edition_url_help: "crwdns38162:0crwdne38162:0"
|
||||
idp_slo_service_url: "crwdns38176:0crwdne38176:0"
|
||||
idp_slo_service_url_help: "crwdns38178:0crwdne38178:0"
|
||||
authn_requests_signed: "crwdns38200:0crwdne38200:0"
|
||||
want_assertions_signed: "crwdns38202:0crwdne38202:0"
|
||||
sp_certificate: "crwdns38204:0crwdne38204:0"
|
||||
sp_private_key: "crwdns38206:0crwdne38206:0"
|
||||
provider_form:
|
||||
name: "crwdns26204:0crwdne26204:0"
|
||||
authentication_type: "crwdns26206:0crwdne26206:0"
|
||||
@ -1787,6 +1791,8 @@ zu:
|
||||
fab_analytics: "crwdns26580:0crwdne26580:0"
|
||||
phone_required: "crwdns26582:0crwdne26582:0"
|
||||
address_required: "crwdns26584:0crwdne26584:0"
|
||||
gender_required: "crwdns38196:0crwdne38196:0"
|
||||
birthday_required: "crwdns38198:0crwdne38198:0"
|
||||
tracking_id: "crwdns26586:0crwdne26586:0"
|
||||
facebook_app_id: "crwdns26588:0crwdne26588:0"
|
||||
twitter_analytics: "crwdns26590:0crwdne26590:0"
|
||||
@ -1839,6 +1845,12 @@ zu:
|
||||
address: "crwdns26676:0crwdne26676:0"
|
||||
address_required_info_html: "crwdns26678:0crwdne26678:0"
|
||||
address_is_required: "crwdns26680:0crwdne26680:0"
|
||||
gender: "crwdns38184:0crwdne38184:0"
|
||||
gender_is_required: "crwdns38186:0crwdne38186:0"
|
||||
gender_required_info: "crwdns38188:0crwdne38188:0"
|
||||
birthday: "crwdns38190:0crwdne38190:0"
|
||||
birthday_is_required: "crwdns38192:0crwdne38192:0"
|
||||
birthday_required_info: "crwdns38194:0crwdne38194:0"
|
||||
external_id: "crwdns32051:0crwdne32051:0"
|
||||
external_id_info_html: "crwdns36043:0crwdne36043:0"
|
||||
enable_external_id: "crwdns32055:0crwdne32055:0"
|
||||
|
@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddSpCertificateToSamlProvider < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :saml_providers, :sp_certificate, :string
|
||||
add_column :saml_providers, :sp_private_key, :string
|
||||
add_column :saml_providers, :authn_requests_signed, :boolean, default: false
|
||||
add_column :saml_providers, :want_assertions_signed, :boolean, default: false
|
||||
end
|
||||
end
|
@ -742,3 +742,8 @@ Setting.set('reservation_context_feature', false) unless Setting.find_by(name: '
|
||||
|
||||
Setting.set('family_account', false) unless Setting.find_by(name: 'family_account').try(:value)
|
||||
Setting.set('child_validation_required', false) unless Setting.find_by(name: 'child_validation_required').try(:value)
|
||||
|
||||
Setting.set('phone_required', false) unless Setting.find_by(name: 'phone_required').try(:value)
|
||||
Setting.set('address_required', false) unless Setting.find_by(name: 'address_required').try(:value)
|
||||
Setting.set('gender_required', true) unless Setting.find_by(name: 'gender_required').try(:value)
|
||||
Setting.set('birthday_required', true) unless Setting.find_by(name: 'birthday_required').try(:value)
|
||||
|
@ -2242,41 +2242,6 @@ CREATE SEQUENCE public.payment_gateway_objects_id_seq
|
||||
ALTER SEQUENCE public.payment_gateway_objects_id_seq OWNED BY public.payment_gateway_objects.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_infos; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.payment_infos (
|
||||
id bigint NOT NULL,
|
||||
data jsonb,
|
||||
state character varying,
|
||||
payment_for character varying,
|
||||
service character varying,
|
||||
statistic_profile_id bigint,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_infos_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.payment_infos_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_infos_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.payment_infos_id_seq OWNED BY public.payment_infos.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_schedule_items; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@ -3279,7 +3244,11 @@ CREATE TABLE public.saml_providers (
|
||||
profile_url character varying,
|
||||
idp_cert character varying,
|
||||
idp_cert_fingerprint character varying,
|
||||
idp_slo_service_url character varying
|
||||
idp_slo_service_url character varying,
|
||||
sp_certificate character varying,
|
||||
sp_private_key character varying,
|
||||
authn_requests_signed boolean DEFAULT false,
|
||||
want_assertions_signed boolean DEFAULT false
|
||||
);
|
||||
|
||||
|
||||
@ -4394,8 +4363,8 @@ CREATE TABLE public.users (
|
||||
is_allow_newsletter boolean,
|
||||
current_sign_in_ip inet,
|
||||
last_sign_in_ip inet,
|
||||
validated_at timestamp without time zone,
|
||||
mapped_from_sso character varying,
|
||||
validated_at timestamp without time zone,
|
||||
supporting_documents_reminder_sent_at timestamp(6) without time zone
|
||||
);
|
||||
|
||||
@ -4948,13 +4917,6 @@ ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('publi
|
||||
ALTER TABLE ONLY public.payment_gateway_objects ALTER COLUMN id SET DEFAULT nextval('public.payment_gateway_objects_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_infos id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_infos ALTER COLUMN id SET DEFAULT nextval('public.payment_infos_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_schedule_items id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@ -5891,14 +5853,6 @@ ALTER TABLE ONLY public.payment_gateway_objects
|
||||
ADD CONSTRAINT payment_gateway_objects_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_infos payment_infos_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_infos
|
||||
ADD CONSTRAINT payment_infos_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_schedule_items payment_schedule_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@ -7112,13 +7066,6 @@ CREATE INDEX index_payment_gateway_objects_on_item_type_and_item_id ON public.pa
|
||||
CREATE INDEX index_payment_gateway_objects_on_payment_gateway_object_id ON public.payment_gateway_objects USING btree (payment_gateway_object_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_payment_infos_on_statistic_profile_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_payment_infos_on_statistic_profile_id ON public.payment_infos USING btree (statistic_profile_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_payment_schedule_items_on_invoice_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@ -7910,6 +7857,14 @@ CREATE INDEX proof_of_identity_type_id_and_proof_of_identity_refusal_id ON publi
|
||||
CREATE UNIQUE INDEX unique_not_null_external_id ON public.invoicing_profiles USING btree (external_id) WHERE (external_id IS NOT NULL);
|
||||
|
||||
|
||||
--
|
||||
-- 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: -
|
||||
--
|
||||
@ -7943,14 +7898,6 @@ ALTER TABLE ONLY public.payment_schedules
|
||||
ADD CONSTRAINT fk_rails_00308dc223 FOREIGN KEY (wallet_transaction_id) REFERENCES public.wallet_transactions(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_infos fk_rails_0308366a58; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_infos
|
||||
ADD CONSTRAINT fk_rails_0308366a58 FOREIGN KEY (statistic_profile_id) REFERENCES public.statistic_profiles(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: cart_item_event_reservation_booking_users fk_rails_0964335a37; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@ -9297,10 +9244,8 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20230328094808'),
|
||||
('20230328094809'),
|
||||
('20230331132506'),
|
||||
('20230509121907'),
|
||||
('20230509161557'),
|
||||
('20230510141305'),
|
||||
('20230511080650'),
|
||||
('20230511081018'),
|
||||
('20230524080448'),
|
||||
('20230524083558'),
|
||||
@ -9316,7 +9261,6 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20230720085857'),
|
||||
('20230728072726'),
|
||||
('20230728090257'),
|
||||
('20230825101952'),
|
||||
('20230828073428'),
|
||||
('20230831103208'),
|
||||
('20230901090637'),
|
||||
@ -9326,6 +9270,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20240116163703'),
|
||||
('20240126145351'),
|
||||
('20240126192110'),
|
||||
('20240220140225');
|
||||
('20240220140225'),
|
||||
('20240327095614');
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fab-manager",
|
||||
"version": "6.3.16",
|
||||
"version": "6.3.17",
|
||||
"description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.",
|
||||
"keywords": [
|
||||
"fablab",
|
||||
|
@ -59,7 +59,8 @@ class Exports::StatisticsExportTest < ActionDispatch::IntegrationTest
|
||||
assert_equal reservation.user.profile.full_name, wb.sheet_data[5][1].value
|
||||
assert_equal reservation.user.email, wb.sheet_data[5][2].value
|
||||
assert_equal reservation.user.profile.phone, wb.sheet_data[5][3].value
|
||||
assert_equal I18n.t("export.#{reservation.user.statistic_profile.str_gender}"), wb.sheet_data[5][4].value
|
||||
assert_equal reservation.user.statistic_profile.str_gender.present? ? I18n.t("export.#{reservation.user.statistic_profile.str_gender}") : '',
|
||||
wb.sheet_data[5][4].value
|
||||
assert_equal reservation.user.statistic_profile.age.to_i, wb.sheet_data[5][5].value
|
||||
assert_equal reservation.reservable.name, wb.sheet_data[5][6].value
|
||||
assert_equal reservation.invoice_items.first.invoice.total / 100.0, wb.sheet_data[5][7].value
|
||||
|
Loading…
x
Reference in New Issue
Block a user