e9f8328404
- Updated CsvExportHelper to support Excel XML format for exporting data, improving compatibility with Excel. - Refactored export logic in DiscountOrdersMainPage, SalesReports, OrderSalesReports, and UserOrderMainPage to utilize the new Excel export method. - Changed file extensions from .csv to .xls for better clarity in exported files. - Improved header and row data handling for consistency in exported reports.
360 lines
11 KiB
C#
360 lines
11 KiB
C#
using System.Text;
|
|
using System.Text.Json;
|
|
using BackOffice.Common.BaseComponents;
|
|
using BackOffice.Common.Utilities;
|
|
using CMSMicroservice.Protobuf.Protos;
|
|
using CMSMicroservice.Protobuf.Protos.UserOrder;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.JSInterop;
|
|
using MudBlazor;
|
|
using DateTimeConverterCL;
|
|
using DataModel = CMSMicroservice.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
|
namespace BackOffice.Pages.UserOrder;
|
|
|
|
public partial class UserOrderMainPage
|
|
{
|
|
[Parameter] public long? UserId { get; set; }
|
|
[Inject] public UserOrderContract.UserOrderContractClient UserOrderContract { get; set; }
|
|
[Inject] public IJSRuntime JsRuntime { get; set; }
|
|
private bool _isLoading = true;
|
|
private MudDataGrid<DataModel> _gridData;
|
|
BasePageComponent _basePage;
|
|
|
|
private long? _orderIdFilter;
|
|
private long? _userIdFilter;
|
|
private long? _transactionIdFilter;
|
|
private int? _paymentStatusFilter;
|
|
private int? _deliveryStatusFilter;
|
|
private int? _paymentMethodFilter;
|
|
private DateTime? _paymentDateFrom;
|
|
private DateTime? _paymentDateTo;
|
|
|
|
private GetAllUserOrderByFilterRequest _request = new() { Filter = new() };
|
|
|
|
|
|
private async Task<GridData<DataModel>> ServerReload(GridState<DataModel> state)
|
|
{
|
|
try
|
|
{
|
|
_request.Filter ??= new();
|
|
_request.PaginationState ??= new();
|
|
_request.PaginationState.PageNumber = state.Page + 1;
|
|
_request.PaginationState.PageSize = state.PageSize;
|
|
|
|
if (_orderIdFilter.HasValue && _orderIdFilter.Value > 0)
|
|
{
|
|
_request.Filter.Id = _orderIdFilter.Value;
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.Id = null;
|
|
}
|
|
|
|
if (UserId.HasValue && UserId.Value > 0)
|
|
{
|
|
_request.Filter.UserId = UserId.Value;
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.UserId = _userIdFilter.HasValue && _userIdFilter.Value > 0
|
|
? _userIdFilter.Value
|
|
: null;
|
|
}
|
|
|
|
if (_paymentDateFrom.HasValue)
|
|
{
|
|
_request.Filter.FromDate =
|
|
Timestamp.FromDateTime(DateTime.SpecifyKind(_paymentDateFrom.Value.Date, DateTimeKind.Utc));
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.FromDate = null;
|
|
}
|
|
|
|
if (_paymentDateTo.HasValue)
|
|
{
|
|
_request.Filter.ToDate =
|
|
Timestamp.FromDateTime(DateTime.SpecifyKind(_paymentDateTo.Value.Date.AddDays(1).AddTicks(-1), DateTimeKind.Utc));
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.ToDate = null;
|
|
}
|
|
|
|
if (_paymentStatusFilter.HasValue)
|
|
{
|
|
_request.Filter.PaymentStatus = (PaymentStatus)_paymentStatusFilter.Value;
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.ClearPaymentStatusItem();
|
|
}
|
|
|
|
if (_deliveryStatusFilter.HasValue)
|
|
{
|
|
_request.Filter.DeliveryStatus = (DeliveryStatus)_deliveryStatusFilter.Value;
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.ClearDeliveryStatusItem();
|
|
}
|
|
|
|
if (_paymentMethodFilter.HasValue)
|
|
{
|
|
_request.Filter.PaymentMethod = (PaymentMethod)_paymentMethodFilter.Value;
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.ClearPaymentMethodItem();
|
|
}
|
|
|
|
if (_transactionIdFilter.HasValue && _transactionIdFilter.Value > 0)
|
|
{
|
|
_request.Filter.TransactionId = _transactionIdFilter.Value;
|
|
}
|
|
else
|
|
{
|
|
_request.Filter.TransactionId = null;
|
|
}
|
|
|
|
var result = await UserOrderContract.GetAllUserOrderByFilterAsync(_request);
|
|
if (result != null && result.Models != null && result.Models.Any())
|
|
{
|
|
return new GridData<DataModel>
|
|
{
|
|
Items = result.Models.ToList(),
|
|
TotalItems = (int)result.MetaData.TotalCount
|
|
};
|
|
}
|
|
|
|
return new GridData<DataModel>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"خطا در بارگذاری سفارشات: {ex.Message}", MudBlazor.Severity.Error);
|
|
return new GridData<DataModel>();
|
|
}
|
|
}
|
|
|
|
private async Task OpenDetails(DataModel model)
|
|
{
|
|
var parameters = new DialogParameters
|
|
{
|
|
{ nameof(BackOffice.Pages.UserOrder.Components.UserOrderDetailsDialog.OrderId), model.Id }
|
|
};
|
|
|
|
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Large, FullWidth = true };
|
|
var dialog =
|
|
await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.UserOrderDetailsDialog>("جزئیات سفارش",
|
|
parameters, options);
|
|
var result = await dialog.Result;
|
|
|
|
if (!result.Canceled)
|
|
{
|
|
ReLoadData();
|
|
}
|
|
}
|
|
|
|
private async Task OnDelete(DataModel model)
|
|
{
|
|
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small };
|
|
bool? result = await DialogService.ShowMessageBox(
|
|
"اخطار",
|
|
$"آیا از حذف سفارش شماره «{model.Id}» مطمئن هستید؟",
|
|
yesText: "حذف", cancelText: "لغو",
|
|
options: options);
|
|
if (result != null && result.Value)
|
|
{
|
|
await UserOrderContract.DeleteUserOrderAsync(new()
|
|
{
|
|
Id = model.Id
|
|
});
|
|
ReLoadData();
|
|
}
|
|
|
|
StateHasChanged();
|
|
}
|
|
|
|
public async void ReLoadData()
|
|
{
|
|
if (_gridData != null)
|
|
await _gridData.ReloadServerData();
|
|
}
|
|
|
|
public async Task OnFilterSubmit()
|
|
{
|
|
_basePage.IsFiltered = true;
|
|
StateHasChanged();
|
|
ReLoadData();
|
|
}
|
|
|
|
public async Task OnFilterCleared()
|
|
{
|
|
_basePage.IsFiltered = false;
|
|
StateHasChanged();
|
|
_request = new() { Filter = new() { } };
|
|
_orderIdFilter = null;
|
|
_userIdFilter = null;
|
|
_transactionIdFilter = null;
|
|
_paymentStatusFilter = null;
|
|
_deliveryStatusFilter = null;
|
|
_paymentDateFrom = null;
|
|
_paymentDateTo = null;
|
|
_paymentMethodFilter = null;
|
|
ReLoadData();
|
|
}
|
|
|
|
private Color GetDeliveryStatusColor(int status)
|
|
{
|
|
return status switch
|
|
{
|
|
1 => Color.Warning, // Pending
|
|
2 => Color.Info, // InTransit
|
|
3 => Color.Success, // Delivered
|
|
4 => Color.Error, // Returned
|
|
5 => Color.Dark, // Cancelled
|
|
6 => Color.Primary, // ReadyForOfficePickup
|
|
_ => Color.Default // None / Unknown
|
|
};
|
|
}
|
|
|
|
private string GetDeliveryStatusText(int status)
|
|
{
|
|
return status switch
|
|
{
|
|
1 => "در انتظار ارسال",
|
|
2 => "تحویل پست",
|
|
3 => "تحویل به مشتری",
|
|
4 => "مرجوع شده",
|
|
5 => "لغو شده",
|
|
6 => "آماده تحویل در دفتر",
|
|
_ => "بدون ارسال / نامشخص"
|
|
};
|
|
}
|
|
|
|
private string GetPaymentMethodText(int method)
|
|
{
|
|
return method switch
|
|
{
|
|
1 => "کیف پول",
|
|
_ => "درگاه پرداخت"
|
|
};
|
|
}
|
|
|
|
// Domain PaymentStatus: Success=0, Reject=1, Pending=2
|
|
private static string GetPaymentStatusText(int status) => status switch
|
|
{
|
|
0 => "پرداخت شده",
|
|
1 => "پرداخت ناموفق",
|
|
2 => "در انتظار پرداخت",
|
|
_ => "نامشخص"
|
|
};
|
|
|
|
private async Task OpenChangeStatus(DataModel model)
|
|
{
|
|
var parameters = new DialogParameters
|
|
{
|
|
{ nameof(BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog.OrderId), model.Id },
|
|
{ nameof(BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog.CurrentStatus), model.DeliveryStatus.GetHashCode() }
|
|
};
|
|
|
|
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
|
|
var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog>(
|
|
"تغییر وضعیت ارسال سفارش", parameters, options);
|
|
var result = await dialog.Result;
|
|
|
|
if (!result.Canceled)
|
|
{
|
|
ReLoadData();
|
|
}
|
|
}
|
|
|
|
private async Task OpenApplyDiscount(DataModel model)
|
|
{
|
|
var parameters = new DialogParameters
|
|
{
|
|
{ nameof(BackOffice.Pages.UserOrder.Components.ApplyDiscountDialog.OrderId), model.Id }
|
|
};
|
|
|
|
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
|
|
var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.ApplyDiscountDialog>(
|
|
"اعمال تخفیف روی سفارش", parameters, options);
|
|
var result = await dialog.Result;
|
|
|
|
if (!result.Canceled)
|
|
{
|
|
ReLoadData();
|
|
}
|
|
}
|
|
|
|
private async Task OpenCancelOrder(DataModel model)
|
|
{
|
|
var parameters = new DialogParameters
|
|
{
|
|
{ nameof(BackOffice.Pages.UserOrder.Components.CancelOrderDialog.OrderId), model.Id }
|
|
};
|
|
|
|
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
|
|
var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.CancelOrderDialog>(
|
|
"لغو سفارش", parameters, options);
|
|
var result = await dialog.Result;
|
|
|
|
if (!result.Canceled)
|
|
{
|
|
ReLoadData();
|
|
}
|
|
}
|
|
|
|
private async Task ExportToExcel()
|
|
{
|
|
try
|
|
{
|
|
var exportRequest = new GetAllUserOrderByFilterRequest
|
|
{
|
|
Filter = _request.Filter ?? new(),
|
|
PaginationState = new PaginationState
|
|
{
|
|
PageNumber = 1,
|
|
PageSize = 1000
|
|
}
|
|
};
|
|
|
|
var result = await UserOrderContract.GetAllUserOrderByFilterAsync(exportRequest);
|
|
|
|
if (result?.Models == null || !result.Models.Any())
|
|
{
|
|
Snackbar.Add("دادهای برای خروجی وجود ندارد.", Severity.Info);
|
|
return;
|
|
}
|
|
|
|
var headers = new[]
|
|
{
|
|
"شناسه", "کاربر", "نام مشتری", "مبلغ", "وضعیت پرداخت", "وضعیت ارسال", "روش پرداخت", "تاریخ پرداخت"
|
|
};
|
|
|
|
var rows = result.Models.Select(o => new object?[]
|
|
{
|
|
o.Id,
|
|
o.UserId,
|
|
CsvExportHelper.CustomerName(o.UserFullName, userId: o.UserId),
|
|
o.Amount,
|
|
GetPaymentStatusText(o.PaymentStatus.GetHashCode()),
|
|
GetDeliveryStatusText(o.DeliveryStatus.GetHashCode()),
|
|
GetPaymentMethodText(o.PaymentMethod.GetHashCode()),
|
|
o.PaymentDate?.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() ?? "-"
|
|
});
|
|
|
|
var filename = $"user-orders-{DateTime.Now:yyyyMMddHHmmss}.xls";
|
|
await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename,
|
|
CsvExportHelper.ToExcelXmlBase64("سفارشها", headers, rows));
|
|
Snackbar.Add("خروجی Excel آماده شد.", Severity.Success);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"خطا در خروجی Excel: {ex.Message}", Severity.Error);
|
|
}
|
|
}
|
|
}
|