mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-28 09:24:24 +01:00
(feat) allow admin configure memeber's profile gender/birthday as required
This commit is contained in:
parent
6db25324d2
commit
e8b59bbdcd
@ -3,6 +3,7 @@
|
||||
## Next release
|
||||
|
||||
- improvement: add loader for create/delete availability slot
|
||||
- improvement: allow admin configure memeber's profile gender/birthday as required
|
||||
- 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
|
||||
|
||||
|
@ -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 />
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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; }],
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
##
|
||||
|
@ -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,
|
||||
|
@ -1839,6 +1839,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"
|
||||
|
@ -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)
|
||||
|
@ -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…
Reference in New Issue
Block a user