1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-29 18:52:22 +01:00

extend subscription UI

This commit is contained in:
Sylvain 2021-10-08 19:14:47 +02:00
parent 2b088ff035
commit e646eb8cb5
9 changed files with 99 additions and 16 deletions

View File

@ -2,7 +2,7 @@
# API Controller for resources of type Subscription
class API::SubscriptionsController < API::ApiController
before_action :set_subscription, only: %i[show edit update destroy]
before_action :set_subscription, only: %i[show payment_details edit update destroy]
before_action :authenticate_user!
def show
@ -26,6 +26,10 @@ class API::SubscriptionsController < API::ApiController
end
end
def payment_details
authorize @subscription
end
private
# Use callbacks to share common setup or constraints between actions.

View File

@ -762,9 +762,19 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
animation: true,
templateUrl: '/admin/subscriptions/expired_at_modal.html',
size: 'lg',
controller: ['$scope', '$uibModalInstance', 'Subscription', function ($scope, $uibModalInstance, Subscription) {
$scope.new_expired_at = angular.copy(subscription.expired_at);
resolve: {
paymentDetails () {
return Subscription.payment_details({ id: subscription.id }).$promise;
}
},
controller: ['$scope', '$uibModalInstance', 'Subscription', 'paymentDetails', function ($scope, $uibModalInstance, Subscription, paymentDetails) {
/* PUBLIC SCOPE */
$scope.expire_at = subscription.expired_at;
$scope.new_expired_at = new Date(subscription.expired_at);
$scope.free = free;
$scope.days = 0;
$scope.payment_details = paymentDetails;
$scope.datePicker = {
opened: false,
format: Fablab.uibDateFormat,
@ -780,6 +790,11 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
return $scope.datePicker.opened = true;
};
$scope.$watch(scope => scope.expire_at
, () => refreshDays());
$scope.$watch(scope => scope.new_expired_at
, () => refreshDays());
$scope.ok = function () {
Subscription.update(
{ id: subscription.id },
@ -796,6 +811,31 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
};
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
/* PRIVATE SCOPE */
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
function initialize () {
if (!free) {
$scope.new_expired_at = moment($scope.expire_at).add(subscription.plan.interval_count, subscription.plan.interval).toDate();
}
}
/**
* Refresh the number of free days depending on the original subscription expiration date and on the new selected date
*/
function refreshDays () {
if (!$scope.new_expired_at || !$scope.expire_at) {
return $scope.days = 0;
}
// 86400000 = 1000 * 3600 * 24 = number of ms per day
$scope.days = Math.round((new Date($scope.new_expired_at).getTime() - new Date($scope.expire_at).getTime()) / 86400000);
}
// !!! MUST BE CALLED AT THE END of the controller
initialize();
}]
});
// once the form was validated successfully ...

View File

@ -5,6 +5,10 @@ Application.Services.factory('Subscription', ['$resource', function ($resource)
{ id: '@id' }, {
update: {
method: 'PUT'
},
payment_details: {
url: '/api/subscriptions/:id/payment_details',
method: 'GET'
}
}
);

View File

@ -78,7 +78,7 @@
</p>
<div ng-hide="user.id === currentUser.id">
<button class="btn btn-default" ng-click="updateSubscriptionModal(subscription, true)" translate>{{ 'app.admin.members_edit.offer_free_days' }}</button>
<button class="btn btn-default" ng-click="updateSubscriptionModal(subscription, false)" translate>{{ 'app.admin.members_edit.extend_subscription' }}</button>
<button class="btn btn-default" ng-click="updateSubscriptionModal(subscription, false)" translate>{{ 'app.admin.members_edit.renew_subscription' }}</button>
</div>
<p class="alert alert-info" ng-show="user.id === currentUser.id" translate>
{{ 'app.admin.members_edit.cannot_extend_own_subscription' }}

View File

@ -4,30 +4,49 @@
<div class="modal-body m-lg">
<div class="alert alert-danger">
<div ng-show="free">
<p translate>{{ 'app.admin.members_edit.you_intentionally_decide_to_extend_the_user_s_subscription_by_offering_him_free_days' }}</p>
<p translate>{{ 'app.admin.members_edit.offer_free_days_infos' }}</p>
<p translate>{{ 'app.admin.members_edit.credits_will_remain_unchanged' }}</p>
</div>
<div ng-hide="free">
<p translate>{{ 'app.admin.members_edit.you_intentionally_decide_to_extend_the_user_s_subscription_by_charging_him_again_for_his_current_subscription' }}</p>
<p translate>{{ 'app.admin.members_edit.renew_subscription_info' }}</p>
<p translate>{{ 'app.admin.members_edit.credits_will_be_reset' }}</p>
<p translate>{{ 'app.admin.members_edit.payment_scheduled' }}</p>
</div>
</div>
<form role="form" name="subscriptionForm" novalidate>
<div class="form-group">
<label translate>{{ 'app.admin.members_edit.until_expiration_date' }}</label>
<label translate>{{ 'app.admin.members_edit.current_expiration_date' }}</label>
<span class="form-control">{{expire_at | amDateFormat:'L LT'}}</span>
</div>
<div class="form-group" ng-hide="free">
<label translate>{{ 'app.admin.members_edit.new_subscription_start' }}</label>
<span class="form-control">{{expire_at | amDateFormat:'L LT'}}</span>
</div>
<div class="form-group">
<label for="subscription[expired_at]" translate>{{ 'app.admin.members_edit.new_expiration_date' }}</label>
<input type="text"
class="form-control"
name="subscription[expired_at]"
id="subscription[expired_at]"
ng-model="new_expired_at"
uib-datepicker-popup="{{datePicker.format}}"
datepicker-options="datePicker.options"
is-open="datePicker.opened"
ng-click="openDatePicker($event)"
min-date="datePicker.minDate"
placeholder=""
ng-readonly="!free"
ng-disabled="!free"
required/>
</div>
<div class="alert alert-info" ng-show="!free">
<p ng-show="payment_details.payment_schedule && payment_details.card" translate>{{ 'app.admin.members_edit.payment_schedule_card' }}</p>
<p ng-show="payment_details.payment_schedule && !payment_details.card" translate>{{ 'app.admin.members_edit.payment_schedule_check' }}</p>
<p ng-show="!payment_details.payment_schedule && payment_details.card" translate>{{ 'app.admin.members_edit.one_payment_card' }}</p>
<p ng-show="!payment_details.payment_schedule && !payment_details.card" translate>{{ 'app.admin.members_edit.one_payment_check' }}</p>
</div>
<div class="form-group" ng-show="free">
<label translate>{{ 'app.admin.members_edit.number_of_free_days' }}</label>
<span class="form-control">{{days}}</span>
</div>
</form>
</div>
<div class="modal-footer">

View File

@ -13,4 +13,8 @@ class SubscriptionPolicy < ApplicationPolicy
def update?
user.admin? || (user.manager? && record.user.id != user.id)
end
def payment_details?
user.admin? || user.manager?
end
end

View File

@ -0,0 +1,4 @@
# frozen_string_literal: true
json.payment_schedule !@subscription.original_payment_schedule.nil?
json.card @subscription.original_invoice&.paid_by_card?

View File

@ -866,7 +866,7 @@ en:
expires_at: "Expires at:"
price_: "Price:"
offer_free_days: "Offer free days"
extend_subscription: "Extend subscription"
renew_subscription: "Renew the subscription"
user_has_no_current_subscription: "User has no current subscription."
subscribe_to_a_plan: "Subscribe to a plan"
trainings: "Trainings"
@ -888,13 +888,19 @@ en:
download_the_invoice: "Download the invoice"
download_the_refund_invoice: "Download the refund invoice"
no_invoices_for_now: "No invoices for now."
expiration_date: "Expiration date"
you_intentionally_decide_to_extend_the_user_s_subscription_by_offering_him_free_days: "You intentionally decide to extend the user's subscription by offering him free days."
current_expiration_date: "Current subscription will expire at:"
expiration_date: "Change subscription expiration date"
offer_free_days_infos: "You are about to extend the user's subscription by offering him free additional days."
credits_will_remain_unchanged: "The balance of free credits (training / machines / spaces) of the user will remain unchanged."
you_intentionally_decide_to_extend_the_user_s_subscription_by_charging_him_again_for_his_current_subscription: "You intentionally decide to extend the user's subscription by charging him again for his current subscription."
renew_subscription_info: "You are about to renew the user's subscription by charging him again for his current subscription."
credits_will_be_reset: "The balance of free credits (training / machines / spaces) of the user will be reset, unused credits will be lost."
payment_scheduled: "If the previous subscription was charged through a payment schedule, this one will be charged the same way, the first deadline being charged right now, then each following month."
until_expiration_date: "Until (expiration date):"
new_subscription_start: "The new subscription will start at:"
new_expiration_date: "New expiration date:"
number_of_free_days: "Number of free days:"
payment_schedule_card: "The previous subscription was charged by card through a payment schedule, this one will be charged the same way. The first deadline will be charged when the current subscription expires, then each following month."
payment_schedule_check: "The previous subscription was charged by check through a payment schedule, this one will be charged the same way. Before confirming please ensure you have all the checks to collect all the monthly payments."
one_payment_card: "The previous subscription was charged by card through a single payment, this one will be charged the same way. The payment will be charged right now."
one_payment_check: "The previous subscription was charged by check through a single payment, this one will be charged the same way. Before confirming please ensure you have collected the payment."
you_successfully_changed_the_expiration_date_of_the_user_s_subscription: "You successfully changed the expiration date of the user's subscription"
a_problem_occurred_while_saving_the_date: "A problem occurred while saving the date."
new_subscription: "New subscription"

View File

@ -98,7 +98,9 @@ Rails.application.routes.draw do
end
resources :groups, only: %i[index create update destroy]
resources :subscriptions, only: %i[show update]
resources :subscriptions, only: %i[show update] do
get 'payment_details', action: 'payment_details', on: :member
end
resources :plan_categories
resources :plans do
get 'durations', on: :collection