mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-29 18:52:22 +01:00
admin interface to list coupons
This commit is contained in:
parent
0eaa81b0ba
commit
ee03f1a79c
@ -3,8 +3,8 @@
|
||||
##
|
||||
# Controller used in the prices edition page
|
||||
##
|
||||
Application.Controllers.controller "EditPricingController", ["$scope", "$state", '$uibModal', 'TrainingsPricing', '$filter', 'Credit', 'Pricing', 'Plan', 'plans', 'groups', 'growl', 'machinesPricesPromise', 'Price', 'dialogs', 'trainingsPricingsPromise', 'trainingsPromise', 'machineCreditsPromise', 'machinesPromise', 'trainingCreditsPromise', '_t'
|
||||
, ($scope, $state, $uibModal, TrainingsPricing, $filter, Credit, Pricing, Plan, plans, groups, growl, machinesPricesPromise, Price, dialogs, trainingsPricingsPromise, trainingsPromise, machineCreditsPromise, machinesPromise, trainingCreditsPromise, _t) ->
|
||||
Application.Controllers.controller "EditPricingController", ["$scope", "$state", '$uibModal', 'TrainingsPricing', '$filter', 'Credit', 'Pricing', 'Plan', 'plans', 'groups', 'growl', 'machinesPricesPromise', 'Price', 'dialogs', 'trainingsPricingsPromise', 'trainingsPromise', 'machineCreditsPromise', 'machinesPromise', 'trainingCreditsPromise', 'couponsPromise', '_t'
|
||||
, ($scope, $state, $uibModal, TrainingsPricing, $filter, Credit, Pricing, Plan, plans, groups, growl, machinesPricesPromise, Price, dialogs, trainingsPricingsPromise, trainingsPromise, machineCreditsPromise, machinesPromise, trainingCreditsPromise, couponsPromise, _t) ->
|
||||
|
||||
### PUBLIC SCOPE ###
|
||||
## List of machines prices (not considering any plan)
|
||||
@ -34,6 +34,9 @@ Application.Controllers.controller "EditPricingController", ["$scope", "$state",
|
||||
## List of machines
|
||||
$scope.machines = machinesPromise
|
||||
|
||||
## List of coupons
|
||||
$scope.coupons = couponsPromise
|
||||
|
||||
## The plans list ordering. Default: by group
|
||||
$scope.orderPlans = 'group_id'
|
||||
|
||||
@ -275,7 +278,7 @@ Application.Controllers.controller "EditPricingController", ["$scope", "$state",
|
||||
##
|
||||
$scope.deletePlan = (plans, id) ->
|
||||
if typeof id != 'number'
|
||||
console.error('[editPricingController::deletePlan] Error: invalid id parameter')
|
||||
console.error('[EditPricingController::deletePlan] Error: invalid id parameter')
|
||||
else
|
||||
# open a confirmation dialog
|
||||
dialogs.confirm
|
||||
@ -287,10 +290,10 @@ Application.Controllers.controller "EditPricingController", ["$scope", "$state",
|
||||
# the admin has confirmed, delete the plan
|
||||
Plan.delete {id: id}, (res) ->
|
||||
growl.success(_t('subscription_plan_was_successfully_deleted'))
|
||||
$scope.plans.splice(findPlanIdxById(plans, id), 1)
|
||||
$scope.plans.splice(findItemIdxById(plans, id), 1)
|
||||
|
||||
, (error) ->
|
||||
console.error('[editPricingController::deletePlan] Error: '+error.statusText) if error.statusText
|
||||
console.error('[EditPricingController::deletePlan] Error: '+error.statusText) if error.statusText
|
||||
growl.error(_t('unable_to_delete_the_specified_subscription_an_error_occurred'))
|
||||
|
||||
|
||||
@ -308,12 +311,50 @@ Application.Controllers.controller "EditPricingController", ["$scope", "$state",
|
||||
|
||||
|
||||
|
||||
### PRIVATE SCOPE ###
|
||||
##
|
||||
# Return a textual status concerning the given coupon
|
||||
# @param coupon {Object}
|
||||
# @return {string}
|
||||
##
|
||||
$scope.getCouponStatus = (coupon) ->
|
||||
unless coupon.active
|
||||
return _t('disabled')
|
||||
unless moment(coupon.valid).isSameOrBefore()
|
||||
return _t('expired')
|
||||
unless coupon.usages <= coupon.max_usages
|
||||
return _t('sold_out')
|
||||
return _t('active')
|
||||
|
||||
findPlanIdxById = (plans, id)->
|
||||
(plans.map (plan)->
|
||||
plan.id
|
||||
).indexOf(id)
|
||||
|
||||
|
||||
##
|
||||
# Delete a coupon from the server's database and, in case of success, from the list in memory
|
||||
# @param coupons {Array<Object>} should be called with $scope.coupons
|
||||
# @param id {number} ID of the coupon to delete
|
||||
##
|
||||
$scope.deleteCoupon = (coupons, id) ->
|
||||
if typeof id != 'number'
|
||||
console.error('[EditPricingController::deleteCoupon] Error: invalid id parameter')
|
||||
else
|
||||
# open a confirmation dialog
|
||||
dialogs.confirm
|
||||
resolve:
|
||||
object: ->
|
||||
title: _t('confirmation_required')
|
||||
msg: _t('do_you_really_want_to_delete_this_coupon')
|
||||
, ->
|
||||
# the admin has confirmed, delete the coupon
|
||||
Coupon.delete {id: id}, (res) ->
|
||||
growl.success(_t('coupon_was_successfully_deleted'))
|
||||
$scope.coupons.splice(findItemIdxById(coupons, id), 1)
|
||||
|
||||
, (error) ->
|
||||
console.error('[EditPricingController::deleteCoupon] Error: '+error.statusText) if error.statusText
|
||||
growl.error(_t('unable_to_delete_the_specified_coupon_an_error_occurred'))
|
||||
|
||||
|
||||
|
||||
### PRIVATE SCOPE ###
|
||||
|
||||
##
|
||||
# Kind of constructor: these actions will be realized first when the controller is loaded
|
||||
@ -329,6 +370,19 @@ Application.Controllers.controller "EditPricingController", ["$scope", "$state",
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Retrieve an item index by its ID from the given array of objects
|
||||
# @param items {Array<{id:number}>}
|
||||
# @param id {number}
|
||||
# @returns {number} item index in the provided array
|
||||
##
|
||||
findItemIdxById = (items, id)->
|
||||
(items.map (item)->
|
||||
item.id
|
||||
).indexOf(id)
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Group the given credits array into a map associating the plan ID with its associated trainings/machines
|
||||
# @return {Object} the association map
|
||||
|
@ -742,6 +742,9 @@ angular.module('application.router', ['ui.router']).
|
||||
trainingCreditsPromise: ['Credit', (Credit) ->
|
||||
Credit.query({creditable_type: 'Training'}).$promise
|
||||
]
|
||||
couponsPromise: ['Coupon', (Coupon) ->
|
||||
Coupon.query().$promise
|
||||
]
|
||||
|
||||
# plans
|
||||
.state 'app.admin.plans',
|
||||
@ -786,6 +789,27 @@ angular.module('application.router', ['ui.router']).
|
||||
Translations.query(['app.admin.plans.edit', 'app.shared.plan']).$promise
|
||||
]
|
||||
|
||||
# coupons
|
||||
.state 'app.admin.coupons.new',
|
||||
url: '/admin/coupons/new'
|
||||
views:
|
||||
'main@':
|
||||
templateUrl: '<%= asset_path "admin/coupons/new.html" %>'
|
||||
controller: 'NewCouponController'
|
||||
resolve:
|
||||
translations: [ 'Translations', (Translations) ->
|
||||
Translations.query(['app.admin.coupons.new', 'app.shared.coupon']).$promise
|
||||
]
|
||||
.state 'app.admin.coupons.edit',
|
||||
url: '/admin/coupons/:id/edit'
|
||||
views:
|
||||
'main@':
|
||||
templateUrl: '<%= asset_path "admin/coupons/edit.html" %>'
|
||||
controller: 'EditCouponController'
|
||||
resolve:
|
||||
translations: [ 'Translations', (Translations) ->
|
||||
Translations.query(['app.admin.coupons.edit', 'app.shared.coupon']).$promise
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
8
app/assets/javascripts/services/coupon.coffee
Normal file
8
app/assets/javascripts/services/coupon.coffee
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict'
|
||||
|
||||
Application.Services.factory 'Coupon', ["$resource", ($resource)->
|
||||
$resource "/api/coupons/:id",
|
||||
{id: "@id"},
|
||||
update:
|
||||
method: 'PUT'
|
||||
]
|
0
app/assets/templates/admin/coupons/_coupon.html.erb
Normal file
0
app/assets/templates/admin/coupons/_coupon.html.erb
Normal file
1
app/assets/templates/admin/coupons/edit.html.erb
Normal file
1
app/assets/templates/admin/coupons/edit.html.erb
Normal file
@ -0,0 +1 @@
|
||||
<ng-include src="'<%= asset_path 'admin/coupons/_coupon.html' %>'"></ng-include>
|
1
app/assets/templates/admin/coupons/new.html.erb
Normal file
1
app/assets/templates/admin/coupons/new.html.erb
Normal file
@ -0,0 +1 @@
|
||||
<ng-include src="'<%= asset_path 'admin/coupons/_coupon.html' %>'"></ng-include>
|
24
app/assets/templates/admin/pricing/coupons.html.erb
Normal file
24
app/assets/templates/admin/pricing/coupons.html.erb
Normal file
@ -0,0 +1,24 @@
|
||||
<h2 translate>{{ 'list_of_the_coupons' }}</h2>
|
||||
|
||||
<button type="button" class="btn btn-warning m-t-lg m-b" ui-sref="app.admin.coupons.new" translate>{{ 'add_a_new_coupon' }}</button>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'name' | translate }}</th>
|
||||
<th>{{ 'percentage_off' | translate }}</th>
|
||||
<th>{{ 'status' | translate }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="coupon in coupons">
|
||||
<td>{{coupon.name}}</td>
|
||||
<td>{{coupon.percent_off}} %</td>
|
||||
<td>{{getCouponStatus(coupon)}}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-default" ui-sref="app.admin.coupons.edit({id:coupon.id})"><i class="fa fa-pencil-square-o"></i></button>
|
||||
<button type="button" class="btn btn-danger" ng-click="deleteCoupon(coupons, coupon.id)"><i class="fa fa-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
@ -36,6 +36,10 @@
|
||||
<uib-tab heading="{{ 'credits' | translate }}">
|
||||
<ng-include src="'<%= asset_path 'admin/pricing/credits.html' %>'"></ng-include>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'coupons' | translate }}">
|
||||
<ng-include src="'<%= asset_path 'admin/pricing/coupons.html' %>'"></ng-include>
|
||||
</uib-tab>
|
||||
</uib-tabset>
|
||||
</div>
|
||||
|
||||
|
@ -142,8 +142,20 @@ en:
|
||||
changes_have_been_successfully_saved: "Changes have been successfully saved."
|
||||
credit_was_successfully_saved: "Credit was successfully saved."
|
||||
do_you_really_want_to_delete_this_subscription_plan: "Do you really want to delete this subscription plan?"
|
||||
subscription_plan_was_successfully_deleted: "Subscription plan was successfully delete."
|
||||
subscription_plan_was_successfully_deleted: "Subscription plan was successfully deleted."
|
||||
unable_to_delete_the_specified_subscription_an_error_occurred: "Unable to delete the specified subscription, an error occurred."
|
||||
coupons: "Coupons"
|
||||
list_of_the_coupons: "List of the coupons"
|
||||
percentage_off: "Percentage off"
|
||||
status: "Status"
|
||||
add_a_new_coupon: "Add a new coupon"
|
||||
disabled: "Disabled"
|
||||
expired: "Expired"
|
||||
sold_out: "Sold out"
|
||||
active: "Active"
|
||||
do_you_really_want_to_delete_this_coupon: "Do you really want to delete this coupon?"
|
||||
coupon_was_successfully_deleted: "Coupon was successfully deleted."
|
||||
unable_to_delete_the_specified_coupon_an_error_occurred: "Unable to delete the specified coupon, an error occurred."
|
||||
|
||||
plans:
|
||||
new:
|
||||
|
@ -144,6 +144,18 @@ fr:
|
||||
do_you_really_want_to_delete_this_subscription_plan: "Êtes-vous sûr(e) de vouloir supprimer cette formule d'abonnement ?"
|
||||
subscription_plan_was_successfully_deleted: "La formule d'abonnement a bien été supprimée."
|
||||
unable_to_delete_the_specified_subscription_an_error_occurred: "Impossible de supprimer l'abonnement spécifié, une erreur s'est produite."
|
||||
coupons: "Codes promotionnels"
|
||||
list_of_the_coupons: "Liste des codes promotionnels"
|
||||
percentage_off: "Pourcentage de réduction"
|
||||
status: "Statut"
|
||||
add_a_new_coupon: "Ajouter un code promotionnel"
|
||||
disabled: "Désactivé"
|
||||
expired: "Expiré"
|
||||
sold_out: "Épuisé"
|
||||
active: "Actif"
|
||||
do_you_really_want_to_delete_this_coupon: "Êtes-vous sûr(e) de vouloir supprimer ce code promotionnel ?"
|
||||
coupon_was_successfully_deleted: "Le code promotionnel a bien été supprimé."
|
||||
unable_to_delete_the_specified_coupon_an_error_occurred: "Impossible de supprimer le code promotionnel, une erreur s'est produite."
|
||||
|
||||
plans:
|
||||
new:
|
||||
|
@ -69,6 +69,7 @@ Rails.application.routes.draw do
|
||||
resources :prices, only: [:index, :update] do
|
||||
post 'compute', on: :collection
|
||||
end
|
||||
resources :coupons
|
||||
|
||||
resources :trainings_pricings, only: [:index, :update]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user