feat(order): enhance order details with user contact information and update Protobuf definitions
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m33s

- Added Phone property to UserAddressDto for capturing the user's mobile number.
- Updated GetOrderByIdQueryHandler to include user mobile in order details.
- Enhanced GetCustomerOrderQueryHandler and GetCustomerOrderResponseDto to include PostalCode and UserMobile.
- Modified userorder.proto to add postal_code and user_mobile fields in GetUserOrderResponse.
- Bumped Protobuf project version to reflect the addition of new features.
This commit is contained in:
masoodafar-web
2026-08-07 15:48:04 +03:30
parent 3810146651
commit 40da1bd8df
8 changed files with 134 additions and 6 deletions
@@ -32,6 +32,8 @@ public class UserAddressDto
public string Title { get; set; }
public string Address { get; set; }
public string PostalCode { get; set; }
/// <summary>شماره تماس سفارش‌دهنده (موبایل کاربر) برای برچسب پست</summary>
public string? Phone { get; set; }
}
public class OrderItemDto
@@ -25,6 +25,7 @@ public class GetOrderByIdQueryHandler : IRequestHandler<GetOrderByIdQuery, Order
var order = await query
.Include(o => o.UserAddress)
.Include(o => o.User)
.Include(o => o.OrderDetails)
.ThenInclude(od => od.Product)
.FirstOrDefaultAsync(cancellationToken);
@@ -50,7 +51,8 @@ public class GetOrderByIdQueryHandler : IRequestHandler<GetOrderByIdQuery, Order
{
Title = order.UserAddress.Title,
Address = order.UserAddress.Address,
PostalCode = order.UserAddress.PostalCode
PostalCode = order.UserAddress.PostalCode,
Phone = order.User?.Mobile
},
Items = order.OrderDetails.Select(od => new OrderItemDto
{
@@ -52,6 +52,8 @@ public class GetCustomerOrderQueryHandler : IRequestHandler<GetCustomerOrderQuer
DeliveryDescription = order.DeliveryDescription ?? "",
UserFullName = $"{order.User?.FirstName ?? ""} {order.User?.LastName ?? ""}".Trim(),
UserNationalCode = order.User?.NationalCode ?? "",
PostalCode = order.UserAddress?.PostalCode ?? "",
UserMobile = order.User?.Mobile ?? "",
VatAmount = order.OrderVAT?.VATAmount ?? 0,
VatPercentage = order.OrderVAT != null ? (double)order.OrderVAT.VATRate * 100 : 0,
FactorDetails = order.FactorDetails?.Select(fd => new FactorDetailDto
@@ -20,6 +20,8 @@ public class GetCustomerOrderResponseDto
public string DeliveryDescription { get; set; }
public string UserFullName { get; set; }
public string UserNationalCode { get; set; }
public string PostalCode { get; set; } = string.Empty;
public string UserMobile { get; set; } = string.Empty;
public long VatAmount { get; set; }
public double VatPercentage { get; set; }
}
@@ -3,7 +3,7 @@
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>0.0.205</Version>
<Version>0.0.206</Version>
<DebugType>None</DebugType>
<DebugSymbols>False</DebugSymbols>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
@@ -220,6 +220,9 @@ message GetUserOrderResponse
google.protobuf.StringValue user_national_code = 16;
// اطلاعات مالیات بر ارزش افزوده
OrderVATInfo vat_info = 17;
// اطلاعات پستی برای برچسب کارتن
google.protobuf.StringValue postal_code = 18;
google.protobuf.StringValue user_mobile = 19;
}
// اطلاعات مالیات بر ارزش افزوده
@@ -141,6 +141,8 @@ public class DiscountOrderService : DiscountOrderContract.DiscountOrderContractB
Address = result.Address.Address ?? "",
PostalCode = result.Address.PostalCode ?? ""
};
if (!string.IsNullOrWhiteSpace(result.Address.Phone))
response.Address.Phone = result.Address.Phone;
}
foreach (var item in result.Items)
@@ -197,9 +199,98 @@ public class DiscountOrderService : DiscountOrderContract.DiscountOrderContractB
return response;
}
public override async Task<GetAllDiscountOrdersResponse> GetAllDiscountOrders(GetAllDiscountOrdersRequest request, ServerCallContext context)
public override async Task<GetAllDiscountOrdersResponse> GetAllDiscountOrders(
GetAllDiscountOrdersRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<GetAllDiscountOrdersRequest, GetAllDiscountOrdersQuery, GetAllDiscountOrdersResponse>(request, context);
// Proto PaymentStatus ≠ Domain PaymentStatus (مقادیر int متفاوت) — Adapt خام باعث باگ لیست/فیلتر می‌شود
if (request.PaymentStatus is 3) // PAYMENT_REFUNDED — در دامنه وجود ندارد
{
return new GetAllDiscountOrdersResponse
{
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{
TotalCount = 0,
PageSize = request.PageSize > 0 ? request.PageSize : 20,
CurrentPage = request.PageNumber > 0 ? request.PageNumber : 1,
TotalPage = 0
}
};
}
var query = new GetAllDiscountOrdersQuery
{
PaginationQuery = new Application.Common.Models.PaginationState
{
PageNumber = request.PageNumber > 0 ? request.PageNumber : 1,
PageSize = request.PageSize > 0 ? request.PageSize : 20
},
UserId = request.UserId,
UserMobile = request.UserMobile,
TrackingCode = request.TrackingCode,
FromDate = request.FromDate?.ToDateTime(),
ToDate = request.ToDate?.ToDateTime(),
MinAmount = request.MinAmount,
MaxAmount = request.MaxAmount
};
if (request.PaymentStatus is int paymentStatus)
query.PaymentStatus = MapProtoPaymentFilterToDomain(paymentStatus);
if (request.DeliveryStatus is int deliveryStatus)
query.DeliveryStatus = MapProtoDeliveryFilterToDomain(deliveryStatus);
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetAllDiscountOrdersResponse
{
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{
TotalCount = result.MetaData.TotalCount,
PageSize = result.MetaData.PageSize,
CurrentPage = result.MetaData.CurrentPage,
TotalPage = result.MetaData.TotalPage,
HasPrevious = result.MetaData.HasPrevious,
HasNext = result.MetaData.HasNext
}
};
foreach (var o in result.Models)
{
var model = new CMSMicroservice.Protobuf.Protos.DiscountOrder.AdminOrderDto
{
Id = o.Id,
UserId = o.UserId,
UserFullName = o.UserFullName ?? string.Empty,
UserMobile = o.UserMobile ?? string.Empty,
TotalAmount = o.TotalAmount,
DiscountBalanceUsed = o.DiscountBalanceUsed,
GatewayAmountPaid = o.GatewayAmountPaid,
VatAmount = o.VatAmount,
PaymentStatus = MapPaymentStatus(o.PaymentStatus),
DeliveryStatus = MapDeliveryStatus(o.DeliveryStatus),
ItemsCount = o.ItemsCount,
Created = Timestamp.FromDateTime(DateTime.SpecifyKind(o.Created, DateTimeKind.Utc))
};
if (o.PaymentDate.HasValue)
model.PaymentDate = Timestamp.FromDateTime(DateTime.SpecifyKind(o.PaymentDate.Value, DateTimeKind.Utc));
if (o.LastModified.HasValue)
model.LastModified = Timestamp.FromDateTime(DateTime.SpecifyKind(o.LastModified.Value, DateTimeKind.Utc));
if (!string.IsNullOrWhiteSpace(o.ShippingAddress))
model.ShippingAddress = o.ShippingAddress;
if (!string.IsNullOrWhiteSpace(o.ReceiverName))
model.ReceiverName = o.ReceiverName;
if (!string.IsNullOrWhiteSpace(o.ReceiverMobile))
model.ReceiverMobile = o.ReceiverMobile;
if (!string.IsNullOrWhiteSpace(o.TrackingCode))
model.TrackingCode = o.TrackingCode;
if (!string.IsNullOrWhiteSpace(o.AdminNote))
model.AdminNote = o.AdminNote;
response.Models.Add(model);
}
return response;
}
public override async Task<GetDiscountSalesReportResponse> GetDiscountSalesReport(GetDiscountSalesReportRequest request, ServerCallContext context)
@@ -359,6 +450,16 @@ public class DiscountOrderService : DiscountOrderContract.DiscountOrderContractB
_ => CMSMicroservice.Protobuf.Protos.DiscountOrder.PaymentStatus.PaymentPending
};
/// <summary>
/// فیلتر UI/proto → دامنه: PENDING=0, COMPLETED=1, FAILED=2
/// </summary>
private static DomainEnums.PaymentStatus MapProtoPaymentFilterToDomain(int protoPaymentStatus) => protoPaymentStatus switch
{
1 => DomainEnums.PaymentStatus.Success, // PAYMENT_COMPLETED
2 => DomainEnums.PaymentStatus.Reject, // PAYMENT_FAILED
_ => DomainEnums.PaymentStatus.Pending // PAYMENT_PENDING (0) و پیش‌فرض
};
private static DeliveryStatus MapDeliveryStatus(DomainEnums.DeliveryStatus status) => status switch
{
DomainEnums.DeliveryStatus.None => DeliveryStatus.DeliveryPending,
@@ -369,4 +470,16 @@ public class DiscountOrderService : DiscountOrderContract.DiscountOrderContractB
DomainEnums.DeliveryStatus.Cancelled => DeliveryStatus.DeliveryCancelled,
_ => DeliveryStatus.DeliveryPending
};
/// <summary>
/// فیلتر UI/proto → دامنه DeliveryStatus
/// </summary>
private static DomainEnums.DeliveryStatus MapProtoDeliveryFilterToDomain(int protoDeliveryStatus) => protoDeliveryStatus switch
{
1 => DomainEnums.DeliveryStatus.Pending, // DELIVERY_PROCESSING
2 => DomainEnums.DeliveryStatus.InTransit, // DELIVERY_SHIPPED
3 => DomainEnums.DeliveryStatus.Delivered, // DELIVERY_DELIVERED
4 => DomainEnums.DeliveryStatus.Cancelled, // DELIVERY_CANCELLED
_ => DomainEnums.DeliveryStatus.None // DELIVERY_PENDING (0)
};
}
@@ -121,7 +121,9 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
TrackingCode = result.TrackingCode,
DeliveryDescription = result.DeliveryDescription,
UserFullName = result.UserFullName,
UserNationalCode = result.UserNationalCode
UserNationalCode = result.UserNationalCode,
PostalCode = result.PostalCode,
UserMobile = result.UserMobile
};
// VAT Info
@@ -789,7 +791,9 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
TrackingCode = result.TrackingCode,
DeliveryDescription = result.DeliveryDescription,
UserFullName = result.UserFullName,
UserNationalCode = result.UserNationalCode
UserNationalCode = result.UserNationalCode,
PostalCode = result.PostalCode,
UserMobile = result.UserMobile
};
// VAT Info