Skip to content

Commit c24f125

Browse files
authored
More fixes for payment dialog and claim page (#1376)
* Display attribute helpers unification * Payment dialog layout and texts * Refactoring of add comment form partial usage * Payment dialog scripting fix
1 parent d0ee6ae commit c24f125

File tree

10 files changed

+107
-94
lines changed

10 files changed

+107
-94
lines changed

src/JoinRpg.Helpers/DisplayAttributeHelper.cs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,67 @@
66

77
namespace JoinRpg.Helpers
88
{
9+
/// <summary>
10+
/// Helpers for attributes with text resources
11+
/// </summary>
912
public static class DisplayAttributeHelper
1013
{
14+
/// <summary>
15+
/// Returns name of a member entry specified by <see cref="DisplayNameAttribute"/> or <see cref="DisplayAttribute"/>
16+
/// </summary>
1117
[NotNull]
12-
public static string GetDisplayName(
13-
this Enum enumValue)
18+
public static string GetDisplayName([NotNull] this MemberInfo propertyInfo)
1419
{
15-
if (enumValue == null)
20+
if (propertyInfo == null)
1621
{
17-
return "";
22+
throw new ArgumentNullException(nameof(propertyInfo));
1823
}
1924

20-
return enumValue.GetAttribute<DisplayAttribute>()?.GetName() ?? enumValue.ToString();
25+
return propertyInfo.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName
26+
?? propertyInfo.GetCustomAttribute<DisplayAttribute>()?.GetName()
27+
?? propertyInfo.Name;
2128
}
2229

23-
public static string? GetShortNameOrDefault([NotNull]
24-
this Enum enumValue)
30+
/// <summary>
31+
/// Returns name specified by <see cref="DisplayNameAttribute"/> or <see cref="DisplayAttribute"/>
32+
/// </summary>
33+
public static string GetDisplayName([NotNull] this Enum enumValue)
2534
{
26-
if (enumValue == null)
35+
if (enumValue is null)
2736
{
2837
throw new ArgumentNullException(nameof(enumValue));
2938
}
3039

31-
return enumValue.GetAttribute<DisplayAttribute>()?.GetShortName();
40+
return enumValue.GetAttribute<DisplayNameAttribute>()?.DisplayName
41+
?? enumValue.GetAttribute<DisplayAttribute>()?.GetName()
42+
?? enumValue.ToString();
3243
}
3344

34-
[NotNull]
35-
public static string GetDisplayName([NotNull]
36-
this PropertyInfo propertyInfo)
45+
/// <summary>
46+
/// Returns short name specified by <see cref="DisplayAttribute"/>
47+
/// </summary>
48+
public static string? GetShortName(this Enum enumValue)
3749
{
38-
if (propertyInfo == null)
50+
if (enumValue == null)
3951
{
40-
throw new ArgumentNullException(nameof(propertyInfo));
52+
throw new ArgumentNullException(nameof(enumValue));
4153
}
4254

43-
return propertyInfo.GetCustomAttribute<DisplayAttribute>()?.Name ?? propertyInfo.Name;
55+
return enumValue.GetAttribute<DisplayAttribute>()?.GetShortName();
4456
}
4557

4658
/// <summary>
47-
/// Returns description for enum value
59+
/// Returns description specified by <see cref="DescriptionAttribute"/> or <see cref="DisplayAttribute"/>
4860
/// </summary>
4961
public static string? GetDescription(this Enum enumValue)
5062
{
51-
if (enumValue == null)
63+
if (enumValue is null)
5264
{
5365
throw new ArgumentNullException(nameof(enumValue));
5466
}
5567

56-
return enumValue.GetAttribute<DisplayAttribute>()
57-
?.Description
58-
?? enumValue.GetAttribute<DescriptionAttribute>()
59-
?.Description;
68+
return enumValue.GetAttribute<DescriptionAttribute>()?.Description
69+
?? enumValue.GetAttribute<DisplayAttribute>()?.GetDescription();
6070
}
6171
}
6272
}

src/JoinRpg.Helpers/StaticEnumHelpers.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,25 @@
66

77
namespace JoinRpg.Helpers
88
{
9+
/// <summary>
10+
/// Helpers for <see cref="Enum"/> type
11+
/// </summary>
912
public static class StaticEnumHelpers
1013
{
14+
/// <summary>
15+
/// Returns custom attribute defined by <typeparamref name="TAttribute"/> attached to an enumeration value
16+
/// </summary>
1117
[PublicAPI, CanBeNull]
1218
public static TAttribute? GetAttribute<TAttribute>(this Enum enumValue)
13-
where TAttribute : Attribute
14-
{
15-
return enumValue.GetType()
19+
where TAttribute : Attribute =>
20+
enumValue.GetType()
1621
.GetField(enumValue.ToString())?
1722
.GetCustomAttribute<TAttribute>();
18-
}
23+
24+
/// <summary>
25+
/// Returns values of an enumeration of type <typeparamref name="T"/>
26+
/// </summary>
27+
[PublicAPI]
28+
public static IEnumerable<T> GetValues<T>() => Enum.GetValues(typeof(T)).Cast<T>();
1929
}
2030
}

src/JoinRpg.Portal/Helpers/EnumExtensions.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/JoinRpg.Portal/Views/Finances/_PayOnlineDialog.cshtml

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
@using JoinRpg.CommonUI.Models
21
@using JoinRpg.Helpers
3-
@using JoinRpg.Web.Helpers
42
@using JoinRpg.Web.Models
53
@model PaymentViewModel
64

@@ -45,7 +43,7 @@
4543
<label for="@Html.IdFor(m => m.Money)" class="col-md-4 control-label">Сумма к оплате:</label>
4644
<div class="col-md-8">
4745
<div>
48-
@Html.EditorFor(m => m.Money, new {htmlAttributes = new {@class = "form-control", style = "display: inline-block; max-width: 150px", min="1", max="100000"}})
46+
@Html.EditorFor(m => m.Money, new {htmlAttributes = new {@class = "form-control", onchange = "changeHandler()", style = "display: inline-block; max-width: 150px", min="1", max="100000"}})
4947
5048
</div>
5149
@Html.ValidationMessageFor(m => m.Money, "", new {@class = "text-danger"})
@@ -61,17 +59,17 @@
6159

6260
<div class="form-group">
6361
<div class="col-md-12">
64-
@Html.CheckBoxFor(m => m.AcceptContract, new { onchange = "dlgPayContractChange()" })
62+
@Html.CheckBoxFor(m => m.AcceptContract, new { onchange = "changeHandler()" })
6563
<label for="@Html.IdFor(m => m.AcceptContract)">Я прочитал(а), понял(а) и принимаю условия @Html.ActionLink("оферты", "user-agreement", "OnlinePayments")</label>
6664
</div>
6765
</div>
6866
</div>
6967
</div>
7068
<div class="modal-footer" style="display: flex; flex-direction: row; align-items: center;">
7169
<button type="button" class="btn btn-default" style="margin-right: auto;" data-dismiss="modal">Отмена</button>
72-
<div style="display: flex; flex-direction: column; align-items: flex-end;">
70+
<div>
7371
<button type="submit" id="dlgPayOnline1Submit" disabled name="@Html.NameFor(m => m.Method)" value="@PaymentMethodViewModel.BankCard" class="btn btn-success" style="font-size: larger;" title="@PaymentMethodViewModel.BankCard.GetDescription()">@PaymentMethodViewModel.BankCard.GetDisplayName()</button>
74-
<button type="submit" id="dlgPayOnline2Submit" disabled name="@Html.NameFor(m => m.Method)" value="@PaymentMethodViewModel.FastPaymentsSystem" class="btn btn-secondary" style="font-size: larger; margin-top: 0.5em" title="@PaymentMethodViewModel.FastPaymentsSystem.GetDescription()">@PaymentMethodViewModel.FastPaymentsSystem.GetDisplayName()</button>
72+
<button type="submit" id="dlgPayOnline2Submit" disabled name="@Html.NameFor(m => m.Method)" value="@PaymentMethodViewModel.FastPaymentsSystem" class="btn btn-secondary" style="font-size: larger; margin-left: 0.5em;" title="@PaymentMethodViewModel.FastPaymentsSystem.GetDescription()">@PaymentMethodViewModel.FastPaymentsSystem.GetDisplayName()</button>
7573
</div>
7674
</div>
7775
}
@@ -80,19 +78,19 @@
8078
</div>
8179

8280
<script type="text/javascript" defer>
83-
function dlgPayContractChange()
84-
{
85-
const edMoney = document.getElementById('@Html.IdFor(m => m.Money)');
86-
const checkBox = document.getElementById('@Html.IdFor(m => m.AcceptContract)');
87-
const submitBtn1 = document.getElementById('dlgPayOnline1Submit');
88-
const submitBtn2 = document.getElementById('dlgPayOnline2Submit');
89-
const money = parseInt(edMoney.value);
90-
if (money >= 1 && money <= 100000 && checkBox.checked) {
91-
submitBtn1.removeAttribute('disabled');
92-
submitBtn2.removeAttribute('disabled');
93-
} else {
94-
submitBtn1.setAttribute('disabled', '');
95-
submitBtn2.setAttribute('disabled', '');
96-
}
97-
}
81+
function changeHandler()
82+
{
83+
const edMoney = document.getElementById('@Html.IdFor(m => m.Money)');
84+
const checkBox = document.getElementById('@Html.IdFor(m => m.AcceptContract)');
85+
const submitBtn1 = document.getElementById('dlgPayOnline1Submit');
86+
const submitBtn2 = document.getElementById('dlgPayOnline2Submit');
87+
const money = parseInt(edMoney.value);
88+
if (money >= 1 && money <= 100000 && checkBox.checked) {
89+
submitBtn1.removeAttribute('disabled');
90+
submitBtn2.removeAttribute('disabled');
91+
} else {
92+
submitBtn1.setAttribute('disabled', '');
93+
submitBtn2.setAttribute('disabled', '');
94+
}
95+
}
9896
</script>
Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
1-
<p>
2-
После нажатия кнопки «Оплатить» вы будете перенаправлены на страницу платежного сервиса
3-
«ПСКБ Онлайн» для ввода данных своей банковской карты (поддерживаются карты Master Card, Visa или МИР).
4-
Если банк, выдавший вам карту, требует дополнительную проверку, то произойдет переадресация на страницу
5-
банка для ввода одноразового пароля (технология 3D Secure).
1+
@using JoinRpg.Web.Models
2+
@using JoinRpg.Helpers
3+
<p>
4+
<strong>Оплата картой.</strong>
5+
После нажатия кнопки «@PaymentMethodViewModel.BankCard.GetDisplayName()» вы будете перенаправлены
6+
на страницу платежного сервиса «ПСКБ Онлайн» для ввода данных своей банковской карты. Поддерживаются
7+
карты Master Card, Visa или МИР, а также сервисы Apple Pay (только в браузере Safari на устройствах Apple),
8+
Google Pay, Samsung Pay. Если банк, выдавший вам карту, требует дополнительную проверку,
9+
то произойдет переадресация на страницу банка для ввода одноразового пароля (технология 3D Secure).
10+
</p>
11+
<p>
12+
<strong>Оплата по QR-коду.</strong>
13+
После нажатия кнопки «@PaymentMethodViewModel.FastPaymentsSystem.GetDisplayName()» вы будете
14+
перенаправлены на страницу платежного сервиса «ПСКБ Онлайн», на которой произойдет отображение
15+
QR-кода <a target="_blank" href="https://sbp.nspk.ru/">Системы Быстрых Платежей</a>. Для выполнения
16+
оплаты мобильное приложение вашего банка должно поддерживать оплату по QR-коду.
617
</p>
718
<p>
8-
JoinRpg.Ru не имеет доступа к данным вашей карты, и соответственно не обрабатывает и не хранит их,
9-
они обрабатываются платежным сервисом «ПСКБ Онлайн» согласно требованиям стандарта безопасности PCI&nbsp;DSS&nbsp;3.0,
10-
передаются через соединение, зашифрованное по технологии SSL. Безопасность гарантирует
11-
<a target="_blank" href="https://pscb.ru">АО&nbsp;Банк&nbsp;«ПСКБ»</a>.
19+
JoinRpg.Ru не имеет доступа к данным вашей карты или банковского аккаунта, и соответственно
20+
не обрабатывает и не хранит их, они обрабатываются платежным сервисом «ПСКБ Онлайн» согласно
21+
требованиям стандарта безопасности PCI&nbsp;DSS&nbsp;3.0, передаются через соединение, зашифрованное
22+
по технологии SSL. Безопасность гарантирует <a target="_blank" href="https://pscb.ru">АО&nbsp;Банк&nbsp;«ПСКБ»</a>.
1223
</p>
1324
<p>
14-
Успешная оплата будет автоматически отмечена в базе, а вы получите чек на свою электронную почту.
15-
Дополнительно информировать организаторов (мастеров) или отмечать оплату вручную не требуется.
25+
Успешная оплата будет автоматически отмечена в базе, а вы получите чек на свою электронную почту.
26+
Дополнительно информировать организаторов (мастеров) или отмечать оплату вручную не требуется.
1627
</p>

src/JoinRpg.Portal/Views/Shared/Components/Comment/Comment.cshtml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,18 @@
130130
Ответить
131131
</a>
132132
<div id="answerComment@(comment.CommentId)" class="collapse">
133-
<partial name="../Comments/_AddCommentFormPartial"
134-
model="@new AddCommentViewModel { ProjectId = comment.ProjectId, CommentDiscussionId = comment.CommentDiscussionId, ParentCommentId = comment.CommentId, EnableFinanceAction = comment.ShowFinanceModeration, EnableHideFromUser = comment.HasMasterAccess, HideFromUser = !comment.IsVisibleToPlayer }" />
133+
@{
134+
var addCommentModel = new AddCommentViewModel
135+
{
136+
ProjectId = comment.ProjectId,
137+
CommentDiscussionId = comment.CommentDiscussionId,
138+
ParentCommentId = comment.CommentId,
139+
EnableFinanceAction = comment.ShowFinanceModeration,
140+
EnableHideFromUser = comment.HasMasterAccess,
141+
HideFromUser = !comment.IsVisibleToPlayer
142+
};
143+
}
144+
<partial name="../Comments/_AddCommentFormPartial" model="@addCommentModel"/>
135145
</div>
136146
</div>
137147
</td>
@@ -144,9 +154,9 @@
144154

145155
@foreach (var childComment in comment.ChildComments)
146156
{
147-
var style = Model.DeepLevel < 4 ? "margin-left:2em" : "";
157+
string style = Model.DeepLevel < 4 ? "margin-left:2em" : "";
148158
<div style="@style">
149-
<vc:comment comment="@childComment"></vc:comment>
159+
<vc:comment comment="@childComment" />
150160
</div>
151161
}
152162
</div>

src/JoinRpg.Services.Email/EmailServiceImpl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ private async Task SendClaimEmail([NotNull] ClaimEmailModel model, string? actio
378378

379379
var extraText = commentExtraActionView?.GetDisplayName();
380380

381-
actionName ??= commentExtraActionView?.GetShortNameOrDefault() ?? "изменена";
381+
actionName ??= commentExtraActionView?.GetShortName() ?? "изменена";
382382

383383
if (extraText != null)
384384
{

src/JoinRpg.Services.Impl/AccommodationServiceImpl.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public async Task<IEnumerable<ProjectAccommodation>> AddRooms(int projectId, int
220220

221221
if (roomType.ProjectId != projectId)
222222
{
223-
throw new ArgumentException($"Room type {roomTypeId} is from another project than specified", nameof(roomTypeId));
223+
throw new ArgumentException($@"Room type {roomTypeId} is from another project than specified", nameof(roomTypeId));
224224
}
225225

226226
// Internal function
@@ -280,14 +280,14 @@ private ProjectAccommodation GetRoom(int roomId, int? projectId = null, int? roo
280280
{
281281
if (result.ProjectId != projectId.Value)
282282
{
283-
throw new ArgumentException($"Room {roomId} is from different project than specified", nameof(projectId));
283+
throw new ArgumentException($@"Room {roomId} is from different project than specified", nameof(projectId));
284284
}
285285
}
286286
if (roomTypeId.HasValue)
287287
{
288288
if (result.AccommodationTypeId != roomTypeId.Value)
289289
{
290-
throw new ArgumentException($"Room {roomId} is from different room type than specified", nameof(projectId));
290+
throw new ArgumentException($@"Room {roomId} is from different room type than specified", nameof(projectId));
291291
}
292292
}
293293

src/JoinRpg.WebPortal.Models/ClaimViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ public FinanceOperationViewModel(FinanceOperation source, bool isMaster)
438438
Description = OperationState.GetDisplayName();
439439
break;
440440
case FinanceOperationTypeViewModel.Online when source.Approved:
441-
Description = OperationState.GetShortNameOrDefault() ?? "";
441+
Description = OperationState.GetShortName() ?? "";
442442
break;
443443
case FinanceOperationTypeViewModel.Online when source.State == FinanceOperationState.Invalid:
444444
Description = OperationState.GetDisplayName();

src/JoinRpg.WebPortal.Models/Money/PaymentViewModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace JoinRpg.Web.Models
99
{
1010
public enum PaymentMethodViewModel
1111
{
12-
[Display(Name = "Оплатить картой", Description = "Оплата банковской картой или при помощи систем Apply Pay или Samsung Pay")]
12+
[Display(Name = "Оплатить картой", Description = "Оплата банковской картой или при помощи систем Apply Pay, Google Pay, Samsung Pay")]
1313
BankCard = PaymentMethod.BankCard,
1414

15-
[Display(Name = "Оплатить по QR-коду", Description = "Оплата через систему быстрых платежей при помощи QR-кода. У вас должно быть установлено приложение вашего банка и он должен поддерживать оплату по QR-коду.")]
15+
[Display(Name = "Оплатить по QR-коду", Description = "Оплата через Систему Быстрых Платежей при помощи QR-кода. У вас должно быть установлено мобильное приложение вашего банка и оно должно поддерживать оплату по QR-коду.")]
1616
FastPaymentsSystem = PaymentMethod.FastPaymentsSystem,
1717
}
1818

0 commit comments

Comments
 (0)