1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-19 13:54:25 +01:00

add notification and alert when user wallet credit

This commit is contained in:
Peng DU 2016-07-05 19:07:50 +02:00
parent d0956bb0aa
commit fc7eaaab94
21 changed files with 190 additions and 4 deletions

View File

@ -260,8 +260,8 @@ Application.Controllers.controller "AdminMembersController", ["$scope", 'members
##
# Controller used in the member edition page
##
Application.Controllers.controller "EditMemberController", ["$scope", "$state", "$stateParams", "Member", 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise'
, ($scope, $state, $stateParams, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise) ->
Application.Controllers.controller "EditMemberController", ["$scope", "$state", "$stateParams", "Member", 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise', 'Wallet'
, ($scope, $state, $stateParams, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise, Wallet) ->
@ -403,6 +403,39 @@ Application.Controllers.controller "EditMemberController", ["$scope", "$state",
$scope.subscription = subscription
$scope.createWalletCreditModal = (user, wallet)->
modalInstance = $uibModal.open
animation: true,
templateUrl: '<%= asset_path "wallet/credit_modal.html" %>'
controller: ['$scope', '$uibModalInstance', 'Wallet', '$locale', ($scope, $uibModalInstance, Wallet, $locale) ->
## currency symbol for the current locale (cf. angular-i18n)
$scope.currencySymbol = $locale.NUMBER_FORMATS.CURRENCY_SYM
##
# Modal dialog validation callback
##
$scope.ok = ->
Wallet.credit { id: wallet.id }, { amount: $scope.amount }, (_wallet)->
growl.success(_t('wallet_credit_successfully'))
$uibModalInstance.close(_wallet)
, (error)->
growl.error(_t('a_problem_occurred_for_wallet_credit'))
##
# Modal dialog cancellation callback
##
$scope.cancel = ->
$uibModalInstance.dismiss('cancel')
]
# once the form was validated succesfully ...
modalInstance.result.then (wallet) ->
$scope.wallet = wallet
Wallet.transactions {id: wallet.id}, (transactions) ->
$scope.transactions = transactions
### PRIVATE SCOPE ###

View File

@ -15,4 +15,8 @@ Application.Services.factory 'Wallet', ["$resource", ($resource)->
method: 'GET'
url: '/api/wallet/:id/transactions'
isArray: true
credit:
method: 'PUT'
url: '/api/wallet/:id/credit'
isArray: false
]

View File

@ -539,3 +539,23 @@ padding: 10px;
}
}
.amountGroup {
input {
display: inline-block;
width: 100px;
margin-left: 5px;
padding-right: 6px;
font-weight: bold;
color: $green;
font-size: 1.2em;
line-height: 0;
}
.afterAmount {
margin-left: -35px;
font-weight: bold;
color: $green;
font-size: 1.2em;
line-height: 0;
}
}

View File

@ -219,6 +219,12 @@
<uib-tab heading="{{ 'wallet' | translate }}">
<div class="col-md-12 m m-t-lg">
<ng-include src="'<%= asset_path 'wallet/show.html' %>'"></ng-include>
<div class="clearfix"></div>
<div class="col-sm-4 text-center">
<button type="button" class="btn btn-warning m-t m-b" ng-click="createWalletCreditModal(user, wallet)" translate>{{ 'to_credit' }}</button>
</div>
</div>
<div class="col-md-12 m m-t-lg">

View File

@ -0,0 +1,20 @@
<div class="modal-header">
<img ng-src="{{logoBlack.custom_asset_file_attributes.attachment_url}}" alt="{{logo.custom_asset_file_attributes.attachment}}" class="modal-logo"/>
<h1 translate>{{ 'credit' }}</h1>
</div>
<div class="modal-body">
<form name="walletForm" ng-class="{'has-error': walletForm.amount.$dirty && walletForm.amount.$invalid}">
<div class="text-center amountGroup">
<span class="beforeAmount" translate>{{ 'to_credit' }}</span>
<input class="form-control" type="number" name="amount" ng-model="amount" required min="1" step="any">
<span class="afterAmount">{{currencySymbol}}</span>
<span class="help-block" ng-show="walletForm.amount.$dirty && walletForm.amount.$error.required" translate>{{'amount_is_required'}}</span>
<span class="help-block" ng-show="walletForm.amount.$dirty && walletForm.amount.$error.min">{{ 'amount_minimum_1' | translate }}{{currencySymbol}}</span>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-info" ng-click="ok()" ng-disabled="walletForm.$invalid || attempting" translate>{{ 'confirm' }}</button>
<button class="btn btn-default" ng-click="cancel()" translate>{{ 'cancel' }}</button>
</div>

View File

@ -17,4 +17,15 @@ class API::WalletController < API::ApiController
authorize @wallet
@wallet_transactions = @wallet.wallet_transactions.includes(:transactable, user: [:profile]).order(created_at: :desc)
end
def credit
@wallet = Wallet.find(params[:id])
authorize @wallet
service = WalletService.new(user: current_user, wallet: @wallet)
if service.credit(params[:amount].to_f)
render :show
else
head 422
end
end
end

View File

@ -37,5 +37,7 @@ class NotificationType
notify_admin_profile_complete
notify_admin_abuse_reported
notify_admin_invoicing_changed
notify_user_wallet_is_credited
notify_admin_user_wallet_is_credited
)
end

View File

@ -6,4 +6,8 @@ class WalletPolicy < ApplicationPolicy
def transactions?
user.is_admin? or user == record.user
end
def credit?
user.is_admin?
end
end

View File

@ -6,7 +6,14 @@ class WalletService
def credit(amount)
if @wallet.credit(amount)
WalletTransaction.create(user: @user, wallet: @wallet, transaction_type: 'credit', amount: amount)
transaction = WalletTransaction.create(user: @user, wallet: @wallet, transaction_type: 'credit', amount: amount)
NotificationCenter.call type: 'notify_user_wallet_is_credited',
receiver: @wallet.user,
attached_object: transaction
NotificationCenter.call type: 'notify_admin_user_wallet_is_credited',
receiver: User.admins,
attached_object: transaction
return true
end
end

View File

@ -0,0 +1,7 @@
json.title notification.notification_type
amount = notification.attached_object.amount
json.description t('.wallet_is_credited',
AMOUNT: number_to_currency(amount),
USER: notification.attached_object.wallet.user.profile.full_name,
ADMIN: notification.attached_object.user.profile.full_name)
json.url notification_url(notification, format: :json)

View File

@ -0,0 +1,5 @@
json.title notification.notification_type
amount = notification.attached_object.amount
json.description t('.your_wallet_is_credited',
AMOUNT: number_to_currency(amount))
json.url notification_url(notification, format: :json)

View File

@ -0,0 +1,9 @@
<%# this is a mail template of notifcation notify_admin_user_wallet_is_credited %>
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
<p>
<%= t('.body.wallet_credit_html',
AMOUNT: number_to_currency(@attached_object.amount),
USER: @attached_object.wallet.user.profile.full_name,
ADMIN: @attached_object.user.profile.full_name)
%>
</p>

View File

@ -0,0 +1,2 @@
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
<p><%= t('.body.wallet_credit_html', AMOUNT: number_to_currency(@attached_object.amount)) %></p>

View File

@ -304,4 +304,7 @@ en:
operation: 'Operation'
operator: 'Operator'
amount: 'Amount'
credit: 'Crédit'
credit: 'Credit'
to_credit: 'Credit'
wallet_credit_successfully: "Wallet of user is credited successfully."
a_problem_occurred_for_wallet_credit: "A problem is occurred while taking the credit of wallet"

View File

@ -305,3 +305,8 @@ fr:
operator: 'Opérateur'
amount: 'Montant'
credit: 'Crédit'
to_credit: 'Créditer'
wallet_credit_successfully: "Le porte-monnaie d'utilisateur a été chargé avec succès."
a_problem_occurred_for_wallet_credit: "Il y a eu un problème lors de chargement au porte-monnaie d'utilisateur."
amount_is_required: "Le montant est obligatoire"
amount_minimum_1: "Le montant minimum est d'1"

View File

@ -229,6 +229,10 @@ en:
undefined_notification:
unknown_notification: "Unknown notification"
notification_ID_wrong_type_TYPE_unknown: "Notification %{ID} wrong (type %{TYPE} unknown)"
notify_user_wallet_is_credited:
your_wallet_is_credited: "Your wallet is credited"
notify_admin_user_wallet_is_credited:
wallet_is_credited: "The wallet of %{USER} is credited %{AMOUNT}"
statistics:
# statistics tools for admins

View File

@ -229,6 +229,10 @@ fr:
undefined_notification:
unknown_notification: "Notification inconnue"
notification_ID_wrong_type_TYPE_unknown: "Notification {ID} erronée (type {TYPE} inconnu)."
notify_user_wallet_is_credited:
your_wallet_is_credited: "Votre porte-monnaie est chargé %{AMOUNT}"
notify_admin_user_wallet_is_credited:
wallet_is_credited: "Le porte-monnaie de %{USER} est chargé %{AMOUNT}"
statistics:
# outil de statistiques pour les administrateurs

View File

@ -240,5 +240,15 @@ en:
disabled: "From now on, no invoice will be issued when the user pays at the reception."
enabled: "From now on, all payments made by this user at the reception will lead to invoicing issuing. "
notify_user_wallet_is_credited:
subject: "Your wallet is credited"
body:
wallet_credit_html: "Your wallet is credited %{AMOUNT}."
notify_admin_user_wallet_is_credited:
subject: "The wallet of an user is credited"
body:
wallet_credit_html: "The wallet of %{USER} is credited %{AMOUNT} by %{ADMIN}."
shared:
hello: "Hello %{user_name}"

View File

@ -240,5 +240,15 @@ fr:
disabled: "Désormais, aucune facture ne sera générée pour les paiement de cet utilisateur effectués à l'accueil."
enabled: "Désormais, tous les paiement de cet utilisateur effectués à l'accueil, donneront lieu à la génération d'une facture."
notify_user_wallet_is_credited:
subject: "Votre porte-monnaie est chargé"
body:
wallet_credit_html: "Votre porte-monnaie est chargé %{AMOUNT}."
notify_admin_user_wallet_is_credited:
subject: "Le porte-monnaie d'un utilisateur est chargé"
body:
wallet_credit_html: "Le porte-monnaie de %{USER} est chargé %{AMOUNT} par %{ADMIN}."
shared:
hello: "Bonjour %{user_name}"

View File

@ -52,6 +52,7 @@ Rails.application.routes.draw do
get :my, on: :collection
get '/by_user/:user_id', action: 'by_user', on: :collection
get :transactions, on: :member
put :credit, on: :member
end
# for homepage

View File

@ -56,4 +56,23 @@ class WalletsTest < ActionDispatch::IntegrationTest
get "/api/wallet/#{user5.wallet.id}/transactions"
assert_equal 403, response.status
end
test 'admin can credit amount to a wallet' do
admin = users(:user_1)
login_as(admin, scope: :user)
w = @kdumas.wallet
amount = 10
expected_amount = w.amount + amount
put "/api/wallet/#{w.id}/credit",
{
amount: amount
}
assert_equal 200, response.status
assert_equal Mime::JSON, response.content_type
wallet = json_response(response.body)
w.reload
assert_equal w.amount, expected_amount
assert_equal w.amount, wallet[:amount]
end
end