85208da1b5
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 1m39s
- Remove manual amount input field - Add package selector dropdown (shows name + price) - Pre-select base package, show price in alert - Validate package selection before submit - Send package_id to CMS, proto NuGet 0.0.192
252 lines
7.5 KiB
C#
252 lines
7.5 KiB
C#
using CMSMicroservice.Protobuf.Protos.ManualPayment;
|
|
using CMSMicroservice.Protobuf.Protos.Package;
|
|
using Google.Protobuf;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components.Forms;
|
|
using MudBlazor;
|
|
|
|
namespace BackOffice.Pages.Payment.Components;
|
|
|
|
public enum ManualPaymentDialogMode
|
|
{
|
|
Create = 0,
|
|
Details = 1
|
|
}
|
|
|
|
public enum ManualPaymentDialogStatus
|
|
{
|
|
Pending = 0,
|
|
Approved = 1,
|
|
Rejected = 2,
|
|
Cancelled = 3
|
|
}
|
|
|
|
public partial class ManualPaymentDialog
|
|
{
|
|
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!;
|
|
[Inject] public ManualPaymentContract.ManualPaymentContractClient ManualPaymentClient { get; set; } = default!;
|
|
[Inject] public PackageContract.PackageContractClient PackageClient { get; set; } = default!;
|
|
// Snackbar is injected via _Imports.razor
|
|
|
|
[Parameter] public ManualPaymentDialogMode Mode { get; set; }
|
|
[Parameter] public ManualPaymentModel? Model { get; set; }
|
|
|
|
private ManualPaymentModel _createModel = new(){ Amount = 0 };
|
|
private string? _adminNote;
|
|
|
|
// User selection
|
|
private long? _selectedUserId;
|
|
|
|
// Package selection
|
|
private long? _selectedPackageId;
|
|
private long? _selectedPackagePrice;
|
|
private List<GetAllPackageByFilterResponseModel> _packages = new();
|
|
|
|
// Type and Description
|
|
private int _selectedType = 1; // Default: CashDeposit
|
|
private string _description = "عضویت دستی باشگاه مشتریان";
|
|
|
|
// Image upload
|
|
private IBrowserFile? _imageFile;
|
|
private string? _imagePreview;
|
|
private const long MaxFileSize = 10 * 1024 * 1024; // 10MB
|
|
|
|
private bool _isSubmitting;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
await LoadPackages();
|
|
}
|
|
|
|
private async Task LoadPackages()
|
|
{
|
|
try
|
|
{
|
|
var request = new GetAllPackageByFilterRequest
|
|
{
|
|
PaginationState = new() { PageNumber = 1, PageSize = 100 },
|
|
Filter = new()
|
|
};
|
|
|
|
var result = await PackageClient.GetAllPackageByFilterAsync(request);
|
|
_packages = result.Models?.OrderBy(p => p.SortOrder).ToList()
|
|
?? new List<GetAllPackageByFilterResponseModel>();
|
|
|
|
// اگر پکیج پایه وجود دارد، پیشفرض انتخاب کن
|
|
var basePackage = _packages.FirstOrDefault(p => p.IsBasePackage);
|
|
if (basePackage != null)
|
|
{
|
|
_selectedPackageId = basePackage.Id;
|
|
_selectedPackagePrice = basePackage.Price;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
_packages = new List<GetAllPackageByFilterResponseModel>();
|
|
}
|
|
}
|
|
|
|
private void OnPackageChanged(long? packageId)
|
|
{
|
|
_selectedPackageId = packageId;
|
|
var pkg = _packages.FirstOrDefault(p => p.Id == packageId);
|
|
_selectedPackagePrice = pkg?.Price;
|
|
}
|
|
|
|
private async Task OnImageFileSelected(IBrowserFile? file)
|
|
{
|
|
if (file == null)
|
|
{
|
|
RemoveImage();
|
|
return;
|
|
}
|
|
|
|
_imageFile = file;
|
|
|
|
// Create preview
|
|
var buffer = new byte[file.Size];
|
|
await file.OpenReadStream(MaxFileSize).ReadAsync(buffer);
|
|
_imagePreview = $"data:{file.ContentType};base64,{Convert.ToBase64String(buffer)}";
|
|
}
|
|
|
|
private void RemoveImage()
|
|
{
|
|
_imageFile = null;
|
|
_imagePreview = null;
|
|
}
|
|
|
|
private async Task CreateAsync()
|
|
{
|
|
if (_isSubmitting) return;
|
|
|
|
// Validation
|
|
if (!_selectedUserId.HasValue || _selectedUserId.Value <= 0)
|
|
{
|
|
Snackbar.Add("لطفاً کاربر را انتخاب کنید.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
if (!_selectedPackageId.HasValue || _selectedPackageId.Value <= 0)
|
|
{
|
|
Snackbar.Add("لطفاً پکیج را انتخاب کنید.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
if (_selectedType <= 0)
|
|
{
|
|
Snackbar.Add("لطفاً نوع پرداخت را انتخاب کنید.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(_description))
|
|
{
|
|
Snackbar.Add("لطفاً توضیحات را وارد کنید.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
_isSubmitting = true;
|
|
StateHasChanged();
|
|
|
|
try
|
|
{
|
|
var request = new CreateManualPaymentRequest
|
|
{
|
|
UserId = _selectedUserId.Value,
|
|
Amount = 0, // deprecated — مبلغ از پکیج خوانده میشود
|
|
PackageId = _selectedPackageId.Value,
|
|
Type = (ManualPaymentType)_selectedType,
|
|
Description = _description
|
|
};
|
|
|
|
if (!string.IsNullOrWhiteSpace(_createModel.ReferenceNumber))
|
|
{
|
|
request.ReferenceNumber = _createModel.ReferenceNumber;
|
|
}
|
|
|
|
// Upload image file
|
|
if (_imageFile != null)
|
|
{
|
|
var buffer = new byte[_imageFile.Size];
|
|
await _imageFile.OpenReadStream(MaxFileSize).ReadAsync(buffer);
|
|
|
|
request.ImageFile = new FileUploadModel
|
|
{
|
|
File = ByteString.CopyFrom(buffer),
|
|
FileName = _imageFile.Name,
|
|
Mime = _imageFile.ContentType
|
|
};
|
|
}
|
|
|
|
await ManualPaymentClient.CreateManualPaymentAsync(request);
|
|
Snackbar.Add("پرداخت دستی با موفقیت ثبت شد.", Severity.Success);
|
|
MudDialog.Close(DialogResult.Ok(true));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"خطا در ثبت پرداخت دستی: {ex.Message}", Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
_isSubmitting = false;
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private async Task ApproveAsync()
|
|
{
|
|
if (Model is null) return;
|
|
|
|
try
|
|
{
|
|
var request = new ApproveManualPaymentRequest
|
|
{
|
|
ManualPaymentId = Model.Id
|
|
};
|
|
|
|
if (!string.IsNullOrWhiteSpace(_adminNote))
|
|
{
|
|
request.ApprovalNote = _adminNote;
|
|
}
|
|
|
|
await ManualPaymentClient.ApproveManualPaymentAsync(request);
|
|
Snackbar.Add("پرداخت دستی تایید شد.", Severity.Success);
|
|
MudDialog.Close(DialogResult.Ok(true));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"خطا در تایید پرداخت دستی: {ex.Message}", Severity.Error);
|
|
}
|
|
}
|
|
|
|
private async Task RejectAsync()
|
|
{
|
|
if (Model is null) return;
|
|
|
|
try
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_adminNote))
|
|
{
|
|
Snackbar.Add("لطفاً دلیل رد را وارد کنید.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
var request = new RejectManualPaymentRequest
|
|
{
|
|
ManualPaymentId = Model.Id,
|
|
RejectionReason = _adminNote
|
|
};
|
|
|
|
await ManualPaymentClient.RejectManualPaymentAsync(request);
|
|
Snackbar.Add("پرداخت دستی رد شد.", Severity.Success);
|
|
MudDialog.Close(DialogResult.Ok(true));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"خطا در رد پرداخت دستی: {ex.Message}", Severity.Error);
|
|
}
|
|
}
|
|
|
|
private void Close() => MudDialog.Close(DialogResult.Cancel());
|
|
}
|
|
|