2018-10-25 16:51:20 +02:00
|
|
|
/* eslint-disable
|
|
|
|
camelcase,
|
|
|
|
handle-callback-err,
|
|
|
|
no-return-assign,
|
|
|
|
no-undef,
|
|
|
|
no-unused-expressions,
|
|
|
|
no-unused-vars,
|
|
|
|
*/
|
|
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
// Fix any style issues and re-enable lint.
|
2018-10-25 16:50:16 +02:00
|
|
|
/*
|
|
|
|
* decaffeinate suggestions:
|
|
|
|
* DS101: Remove unnecessary use of Array.from
|
|
|
|
* DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
* DS205: Consider reworking code to avoid use of IIFEs
|
|
|
|
* DS207: Consider shorter variations of null checks
|
|
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
*/
|
2018-11-21 11:08:53 +01:00
|
|
|
'use strict';
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-10-25 16:50:16 +02:00
|
|
|
/* COMMON CODE */
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-10-25 16:50:16 +02:00
|
|
|
class PlanController {
|
2018-10-25 16:51:20 +02:00
|
|
|
constructor ($scope, groups, prices, partners, CSRF) {
|
2018-10-25 16:50:16 +02:00
|
|
|
// protection against request forgery
|
2018-11-21 11:08:53 +01:00
|
|
|
CSRF.setMetaTags();
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// groups list
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.groups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled; });
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// users with role 'partner', notifiables for a partner plan
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.partners = partners.users;
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// Subscriptions prices, machines prices and training prices, per groups
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.group_pricing = prices;
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* For use with 'ng-class', returns the CSS class name for the uploads previews.
|
|
|
|
* The preview may show a placeholder or the content of the file depending on the upload state.
|
|
|
|
* @param v {*} any attribute, will be tested for truthiness (see JS evaluation rules)
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.fileinputClass = function (v) {
|
2018-10-25 16:50:16 +02:00
|
|
|
if (v) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return 'fileinput-exists';
|
2018-10-25 16:50:16 +02:00
|
|
|
} else {
|
2018-11-21 11:08:53 +01:00
|
|
|
return 'fileinput-new';
|
2018-10-25 16:50:16 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Mark the provided file for deletion
|
|
|
|
* @param file {Object}
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.deleteFile = function (file) {
|
2018-10-25 16:50:16 +02:00
|
|
|
if ((file != null) && (file.id != null)) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return file._destroy = true;
|
2018-10-25 16:50:16 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2018-10-25 16:50:16 +02:00
|
|
|
}
|
|
|
|
}
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Controller used in the plan creation form
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal', 'groups', 'prices', 'partners', 'CSRF', '$state', 'growl', '_t',
|
|
|
|
function ($scope, $uibModal, groups, prices, partners, CSRF, $state, growl, _t) {
|
|
|
|
/* PUBLIC SCOPE */
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// current form is used to create a new plan
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.mode = 'creation';
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// prices bindings
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.prices = {
|
|
|
|
training: {},
|
|
|
|
machine: {}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// form inputs bindings
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.plan = {
|
|
|
|
type: null,
|
|
|
|
group_id: null,
|
|
|
|
interval: null,
|
|
|
|
intervalCount: 0,
|
|
|
|
amount: null,
|
|
|
|
is_rolling: false,
|
|
|
|
partnerId: null,
|
|
|
|
partnerContact: null,
|
|
|
|
ui_weight: 0
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// API URL where the form will be posted
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.actionUrl = '/api/plans/';
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// HTTP method for the rest API
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.method = 'POST';
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Checks if the partner contact is a valid data. Used in the form validation process
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.partnerIsValid = function () { return ($scope.plan.type === 'Plan') || ($scope.plan.partnerId || ($scope.plan.partnerContact && $scope.plan.partnerContact.email)); };
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Open a modal dialog allowing the admin to create a new partner user
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.openPartnerNewModal = function (subscription) {
|
|
|
|
const modalInstance = $uibModal.open({
|
|
|
|
animation: true,
|
|
|
|
templateUrl: '<%= asset_path "shared/_partner_new_modal.html" %>',
|
|
|
|
size: 'lg',
|
|
|
|
controller: ['$scope', '$uibModalInstance', 'User', function ($scope, $uibModalInstance, User) {
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.partner = {};
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-21 10:59:07 +01:00
|
|
|
$scope.ok = function () {
|
2018-11-20 12:26:06 +01:00
|
|
|
User.save(
|
|
|
|
{},
|
|
|
|
{ user: $scope.partner },
|
|
|
|
function (user) {
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.partner.id = user.id;
|
|
|
|
$scope.partner.name = `${user.first_name} ${user.last_name}`;
|
|
|
|
$uibModalInstance.close($scope.partner);
|
2018-11-20 12:26:06 +01:00
|
|
|
},
|
|
|
|
function (error) {
|
2018-11-21 11:08:53 +01:00
|
|
|
growl.error(_t('new_plan.unable_to_save_this_user_check_that_there_isnt_an_already_a_user_with_the_same_name'));
|
|
|
|
console.error(error);
|
2018-11-20 12:26:06 +01:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
);
|
|
|
|
};
|
|
|
|
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
|
2018-11-20 12:26:06 +01:00
|
|
|
}]
|
2018-11-21 11:08:53 +01:00
|
|
|
});
|
2018-11-20 12:26:06 +01:00
|
|
|
// once the form was validated successfully ...
|
2018-10-25 16:51:20 +02:00
|
|
|
return modalInstance.result.then(function (partner) {
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.partners.push(partner);
|
|
|
|
return $scope.plan.partnerId = partner.id;
|
|
|
|
});
|
|
|
|
};
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Display some messages and redirect the user, once the form was submitted, depending on the result status
|
|
|
|
* (failed/succeeded).
|
|
|
|
* @param content {Object}
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.afterSubmit = function (content) {
|
|
|
|
if ((content.id == null) && (content.plan_ids == null)) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return growl.error(_t('new_plan.unable_to_create_the_subscription_please_try_again'));
|
2018-10-25 16:50:16 +02:00
|
|
|
} else {
|
2018-11-21 11:08:53 +01:00
|
|
|
growl.success(_t('new_plan.successfully_created_subscription(s)_dont_forget_to_redefine_prices'));
|
2018-10-25 16:51:20 +02:00
|
|
|
if (content.plan_ids != null) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return $state.go('app.admin.pricing');
|
2018-10-25 16:51:20 +02:00
|
|
|
} else {
|
|
|
|
if (content.id != null) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return $state.go('app.admin.plans.edit', { id: content.id });
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
2018-10-25 16:50:16 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2018-10-25 16:50:16 +02:00
|
|
|
|
2018-11-21 11:08:53 +01:00
|
|
|
return new PlanController($scope, groups, prices, partners, CSRF);
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
]);
|
2018-10-25 16:50:16 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Controller used in the plan edition form
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'plans', 'planPromise', 'machines', 'spaces', 'prices', 'partners', 'CSRF', '$state', '$stateParams', 'growl', '$filter', '_t', 'Plan',
|
|
|
|
function ($scope, groups, plans, planPromise, machines, spaces, prices, partners, CSRF, $state, $stateParams, growl, $filter, _t, Plan) {
|
2018-10-25 16:50:16 +02:00
|
|
|
/* PUBLIC SCOPE */
|
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// List of spaces
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.spaces = spaces;
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// List of plans
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.plans = plans;
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// List of machines
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.machines = machines;
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// List of groups
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.groups = groups;
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// current form is used for edition mode
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.mode = 'edition';
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// edited plan data
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.plan = planPromise;
|
|
|
|
if ($scope.plan.type === null) { $scope.plan.type = 'Plan'; }
|
|
|
|
if ($scope.plan.disabled) { $scope.plan.disabled = 'true'; }
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// API URL where the form will be posted
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.actionUrl = `/api/plans/${$stateParams.id}`;
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
// HTTP method for the rest API
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.method = 'PATCH';
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* If a parent plan was set ($scope.plan.parent), the prices will be copied from this parent plan into
|
|
|
|
* the current plan prices list. Otherwise, the current plan prices will be erased.
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.copyPricesFromPlan = function () {
|
|
|
|
if ($scope.plan.parent) {
|
2018-11-20 12:26:06 +01:00
|
|
|
return Plan.get({ id: $scope.plan.parent }, function (parentPlan) {
|
|
|
|
Array.from(parentPlan.prices).map(function (parentPrice) {
|
|
|
|
return (function () {
|
2018-11-21 11:08:53 +01:00
|
|
|
const result = [];
|
2018-10-25 16:51:20 +02:00
|
|
|
for (let childKey in $scope.plan.prices) {
|
2018-11-21 11:08:53 +01:00
|
|
|
const childPrice = $scope.plan.prices[childKey];
|
2018-10-25 16:51:20 +02:00
|
|
|
if ((childPrice.priceable_type === parentPrice.priceable_type) && (childPrice.priceable_id === parentPrice.priceable_id)) {
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.plan.prices[childKey].amount = parentPrice.amount;
|
|
|
|
break;
|
2018-10-25 16:51:20 +02:00
|
|
|
} else {
|
2018-11-21 11:08:53 +01:00
|
|
|
result.push(undefined);
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
2018-10-25 16:50:16 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
return result;
|
|
|
|
})();
|
|
|
|
});
|
2018-11-21 10:59:07 +01:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
);
|
2018-10-25 16:50:16 +02:00
|
|
|
|
2018-10-25 16:51:20 +02:00
|
|
|
// if no plan were selected, unset every prices
|
|
|
|
} else {
|
2018-11-20 12:26:06 +01:00
|
|
|
return (function () {
|
2018-11-21 11:08:53 +01:00
|
|
|
const result = [];
|
2018-10-25 16:51:20 +02:00
|
|
|
for (let key in $scope.plan.prices) {
|
2018-11-21 11:08:53 +01:00
|
|
|
const price = $scope.plan.prices[key];
|
|
|
|
result.push($scope.plan.prices[key].amount = 0);
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
return result;
|
|
|
|
})();
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2018-10-25 16:50:16 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Display some messages once the form was submitted, depending on the result status (failed/succeeded)
|
|
|
|
* @param content {Object}
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.afterSubmit = function (content) {
|
|
|
|
if ((content.id == null) && (content.plan_ids == null)) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return growl.error(_t('edit_plan.unable_to_save_subscription_changes_please_try_again'));
|
2018-10-25 16:51:20 +02:00
|
|
|
} else {
|
2018-11-21 11:08:53 +01:00
|
|
|
growl.success(_t('edit_plan.subscription_successfully_changed'));
|
|
|
|
return $state.go('app.admin.pricing');
|
2018-10-25 16:50:16 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2018-10-25 16:50:16 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Generate a string identifying the given plan by literal humain-readable name
|
|
|
|
* @param plan {Object} Plan object, as recovered from GET /api/plan/:id
|
|
|
|
* @param groups {Array} List of Groups objects, as recovered from GET /api/groups
|
|
|
|
* @param short {boolean} If true, the generated name will contains the group slug, otherwise the group full name
|
|
|
|
* will be included.
|
|
|
|
* @returns {String}
|
|
|
|
*/
|
2018-11-21 11:08:53 +01:00
|
|
|
$scope.humanReadablePlanName = function (plan, groups, short) { return `${$filter('humanReadablePlanName')(plan, groups, short)}`; };
|
2018-10-25 16:51:20 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the machine from its ID
|
|
|
|
* @param machine_id {number} machine identifier
|
|
|
|
* @returns {Object} Machine
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.getMachine = function (machine_id) {
|
|
|
|
for (let machine of Array.from($scope.machines)) {
|
|
|
|
if (machine.id === machine_id) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return machine;
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
2018-10-25 16:50:16 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2018-10-25 16:50:16 +02:00
|
|
|
|
2018-11-19 16:17:49 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the space from its ID
|
|
|
|
* @param space_id {number} space identifier
|
|
|
|
* @returns {Object} Space
|
|
|
|
*/
|
2018-10-25 16:51:20 +02:00
|
|
|
$scope.getSpace = function (space_id) {
|
|
|
|
for (let space of Array.from($scope.spaces)) {
|
|
|
|
if (space.id === space_id) {
|
2018-11-21 11:08:53 +01:00
|
|
|
return space;
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
};
|
2018-10-25 16:50:16 +02:00
|
|
|
|
|
|
|
// Using the PlansController
|
2018-11-21 11:08:53 +01:00
|
|
|
return new PlanController($scope, groups, prices, partners, CSRF);
|
2018-10-25 16:51:20 +02:00
|
|
|
}
|
2018-11-21 11:08:53 +01:00
|
|
|
]);
|