1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-01 12:24:28 +01:00

plan creation: set if it allows monthly payments

This commit is contained in:
Sylvain 2020-10-27 13:06:37 +01:00
parent 52f3bd956f
commit 5f93e6d3be
8 changed files with 61 additions and 27 deletions

View File

@ -68,7 +68,7 @@ class API::PlansController < API::ApiController
@parameters = @parameters.require(:plan)
.permit(:base_name, :type, :group_id, :amount, :interval, :interval_count, :is_rolling,
:training_credit_nb, :ui_weight, :disabled,
:training_credit_nb, :ui_weight, :disabled, :monthly_payment,
plan_file_attributes: %i[id attachment _destroy],
prices_attributes: %i[id amount])
end

View File

@ -28,15 +28,15 @@ class PlanController {
// groups list
$scope.groups = groups
.filter(function (g) { return (g.slug !== 'admins') && !g.disabled; })
.map(e => Object.assign({}, e, { category: 'app.shared.plan.groups', id: `${e.id}` }))
.map(e => Object.assign({}, e, { category: 'app.shared.plan.groups', id: `${e.id}` }));
$scope.groups.push({ id: 'all', name: 'app.shared.plan.transversal_all_groups', category: 'app.shared.plan.all' });
// dynamically translate a label if needed
$scope.translateLabel = function (group, prop) {
return group[prop] && group[prop].match(/^app\./) ? _t(group[prop]) : group[prop];
}
};
// users with role 'partner', notifiables for a partner plan
// users with role 'partner', notifiable for a partner plan
$scope.partners = partners.users;
// Subscriptions prices, machines prices and training prices, per groups
@ -93,7 +93,8 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
is_rolling: false,
partnerId: null,
partnerContact: null,
ui_weight: 0
ui_weight: 0,
monthly_payment: false
};
// API URL where the form will be posted
@ -144,6 +145,22 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
});
};
/**
* This will update the monthly_payment value when the user toggles the switch button
* @param checked {Boolean}
*/
$scope.toggleMonthlyPayment = function (checked) {
toggle('monthly_payment', checked);
};
/**
* This will update the is_rolling value when the user toggles the switch button
* @param checked {Boolean}
*/
$scope.toggleIsRolling = function (checked) {
toggle('is_rolling', checked);
};
/**
* Display some messages and redirect the user, once the form was submitted, depending on the result status
* (failed/succeeded).
@ -164,6 +181,19 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
}
};
/* PRIVATE SCOPE */
/**
* Asynchronously updates the given property with the new provided value
* @param property {string}
* @param value {*}
*/
const toggle = function (property, value) {
setTimeout(() => {
$scope.plan[property] = value;
$scope.$apply();
}, 50);
};
return new PlanController($scope, groups, prices, partners, CSRF, _t);
}
]);
@ -204,7 +234,7 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
$scope.selectedGroup = function () {
const group = $scope.groups.filter(g => g.id === $scope.plan.group_id);
return $scope.translateLabel(group[0], 'name');
}
};
/**
* If a parent plan was set ($scope.plan.parent), the prices will be copied from this parent plan into
@ -216,7 +246,7 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
Array.from(parentPlan.prices).map(function (parentPrice) {
return (function () {
const result = [];
for (let childKey in $scope.plan.prices) {
for (const childKey in $scope.plan.prices) {
const childPrice = $scope.plan.prices[childKey];
if ((childPrice.priceable_type === parentPrice.priceable_type) && (childPrice.priceable_id === parentPrice.priceable_id)) {
$scope.plan.prices[childKey].amount = parentPrice.amount;
@ -235,7 +265,7 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
} else {
return (function () {
const result = [];
for (let key in $scope.plan.prices) {
for (const key in $scope.plan.prices) {
const price = $scope.plan.prices[key];
result.push($scope.plan.prices[key].amount = 0);
}
@ -273,7 +303,7 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
* @returns {Object} Machine
*/
$scope.getMachine = function (machine_id) {
for (let machine of Array.from($scope.machines)) {
for (const machine of Array.from($scope.machines)) {
if (machine.id === machine_id) {
return machine;
}
@ -286,7 +316,7 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
* @returns {Object} Space
*/
$scope.getSpace = function (space_id) {
for (let space of Array.from($scope.spaces)) {
for (const space of Array.from($scope.spaces)) {
if (space.id === space_id) {
return space;
}

View File

@ -23,10 +23,8 @@ Application.Directives.directive('booleanSetting', ['Setting', 'growl', '_t',
/**
* This will update the value when the user toggles the switch button
* @param checked {Boolean}
* @param event {string}
* @param id {string}
*/
$scope.toggleSetting = (checked, event, id) => {
$scope.toggleSetting = (checked) => {
setTimeout(() => {
$scope.setting.value = checked;
$scope.$apply();

View File

@ -89,6 +89,10 @@
ng-model="plan.amount"/>
</div>
<span class="help-block" ng-show="planForm['plan[amount]'].$dirty && planForm['plan[amount]'].$error.required" translate>{{ 'app.shared.plan.price_is_required' }}</span>
<span class="help-block alert alert-warning" ng-if="method == 'PATCH'">
<i class="fa fa-warning"></i>
{{ 'app.shared.plan.edit_amount_info' | translate }}
</span>
</div>
</div>
@ -106,17 +110,7 @@
<div class="input-group m-t-md">
<label for="plan[is_rolling]" class="control-label m-r-md">{{ 'app.shared.plan.rolling_subscription' | translate }} *</label>
<input bs-switch
ng-model="plan.is_rolling"
id="plan[is_rolling]"
ng-if="method != 'PATCH'"
type="checkbox"
class="form-control"
switch-on-text="{{ 'app.shared.buttons.yes' | translate }}"
switch-off-text="{{ 'app.shared.buttons.no' | translate }}"
switch-animate="true"
ng-true-value="'true'"
ng-false-value="'false'"/>
<switch id="plan[is_rolling]" checked="plan.is_rolling" on-change="toggleIsRolling" class-name="'v-middle'" ng-if="plan && method != 'PATCH'"></switch>
<span ng-if="method == 'PATCH'">{{ (plan.is_rolling ? 'app.shared.buttons.yes' : 'app.shared.buttons.no') | translate }}</span>
<input type="hidden" name="plan[is_rolling]" value="{{plan.is_rolling}}"/>
<span class="help-block">
@ -125,6 +119,13 @@
</span>
</div>
<div class="input-group m-t-md">
<label for="plan[monthly_payment]" class="control-label m-r-md">{{ 'app.shared.plan.monthly_payment' | translate }} *</label>
<switch id="plan[monthly_payment]" checked="plan.monthly_payment" on-change="toggleMonthlyPayment" class-name="'v-middle'" ng-if="plan && method != 'PATCH'"></switch>
<span ng-if="method == 'PATCH'">{{ (plan.monthly_payment ? 'app.shared.buttons.yes' : 'app.shared.buttons.no') | translate }}</span>
<input type="hidden" id="plan_monthly_input" name="plan[monthly_payment]" value="{{plan.monthly_payment}}" />
<span class="help-block" translate>{{ 'app.shared.plan.monthly_payment_info' }}</span>
</div>
<!-- PDF description attachement -->
<input type="hidden" ng-model="plan.plan_file_attributes.id" name="plan[plan_file_attributes][id]" ng-value="plan.plan_file_attributes.id" />

View File

@ -16,7 +16,6 @@
<div class="row no-gutter">
<div class="col-sm-12 col-md-9 b-r">
<my-component foo-bar="3" baz="'hello'"></my-component>
<div class="row m-t m-b padder" ng-repeat="plansGroup in plansClassifiedByGroup | groupFilter:ctrl.member" ng-show="plansGroup.actives > 0">

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
json.extract! plan, :id, :base_name, :name, :interval, :interval_count, :group_id, :training_credit_nb, :is_rolling, :description, :type,
:ui_weight, :disabled
:ui_weight, :disabled, :monthly_payment
json.amount plan.amount / 100.00
json.prices plan.prices, partial: 'api/prices/price', as: :price
if plan.plan_file
@ -17,4 +17,4 @@ if plan.respond_to?(:partners)
json.last_name partner.last_name
json.email partner.email
end
end
end

View File

@ -175,12 +175,15 @@ en:
period_is_required: "Period is required."
subscription_price: "Subscription price"
price_is_required: "Price is required."
edit_amount_info: "Please note that if you change the price of this plan, the new price will only apply to new subscribers. Current subscriptions will stay unchanged, even those with running payment schedule."
visual_prominence_of_the_subscription: "Visual prominence of the subscription"
on_the_subscriptions_page_the_most_prominent_subscriptions_will_be_placed_at_the_top_of_the_list: "On the subscriptions page, the most prominent subscriptions will be placed at the top of the list."
an_evelated_number_means_a_higher_prominence: "An elevated number means a higher prominence."
rolling_subscription: "Rolling subscription?"
a_rolling_subscription_will_begin_the_day_of_the_first_training: "A rolling subscription will begin the day of the first trainings."
otherwise_it_will_begin_as_soon_as_it_is_bought: "Otherwise, it will begin as soon as it is bought."
monthly_payment: "Monthly payment?"
monthly_payment_info: "If monthly payment is enabled, the members will be able to choose between a one-time payment or a payment schedule staged each months."
information_sheet: "Information sheet"
attach_an_information_sheet: "Attach an information sheet"
notified_partner: "Notified partner"

View File

@ -175,12 +175,15 @@ fr:
period_is_required: "La période est requise."
subscription_price: "Coût de l'abonnement"
price_is_required: "Le prix est requis."
edit_amount_info: "Veuillez noter que si vous modifiez le prix de cette formule d'abonnement, le nouveau prix ne s'appliquera qu'aux nouveaux abonnés. Les abonnements actuels resteront inchangés, y-compris ceux ayant un échéancier de paiement est en cours."
visual_prominence_of_the_subscription: "Importance visuelle de l'abonnement"
on_the_subscriptions_page_the_most_prominent_subscriptions_will_be_placed_at_the_top_of_the_list: "Sur la page des abonnements, les abonnements les plus importants seront placés en haut de la liste."
an_evelated_number_means_a_higher_prominence: "Un nombre plus élevé traduit une importance plus élevée."
rolling_subscription: "Abonnement glissant ?"
a_rolling_subscription_will_begin_the_day_of_the_first_training: "Un abonnement glissant prendra effet seulement le jour de la première formation."
otherwise_it_will_begin_as_soon_as_it_is_bought: "Dans le cas contraire, il prendra effet dès sa date d'achat."
monthly_payment: "Paiement mensuel ?"
monthly_payment_info: "Si le paiement mensuel est activé, les membres pourront choisir entre un paiement unique ou un échéancier de paiement échelonné chaque mois."
information_sheet: "Fiche descriptive"
attach_an_information_sheet: "Joindre une fiche descriptive"
notified_partner: "Partenaire notifié"