feat(order): add order detail

This commit is contained in:
morteza-mortezai
2025-09-27 23:32:27 +03:30
parent 79f597cc90
commit 7e344fd695
3 changed files with 265 additions and 0 deletions
@@ -228,4 +228,24 @@ export class AdminOrderController extends BaseController {
const { pager } = this.paginate(data.count);
return this.response({ pager, orders: data.orders, priceRange });
}
@ApiOperation("get an order details of user")
@ApiResponse("successful", HttpStatus.Ok)
@ApiParam("orderId", "id of order", true)
@ApiAuth()
@httpGet("/:orderId/user", Guard.authAdmin(), Guard.checkAdminPermissions([PermissionEnum.ORDER]))
public async getUserOrderDetail(@requestParam("orderId") orderId: string) {
const data = await this.orderService.getAdminUserOrderDetail(+orderId);
return this.response(data);
}
@ApiOperation("get an order details of seller")
@ApiResponse("successful", HttpStatus.Ok)
@ApiParam("orderId", "id of order", true)
@ApiAuth()
@httpGet("/:orderId/seller", Guard.authAdmin(), Guard.checkAdminPermissions([PermissionEnum.ORDER]))
public async getSellerOrderDetail(@requestParam("orderId") orderId: string) {
const data = await this.orderService.getAdminSellerOrderDetail(+orderId);
return this.response(data);
}
}
+198
View File
@@ -1641,6 +1641,204 @@ class OrderItemRepo extends BaseRepository<IOrderItem> {
]);
}
async getSellerOrderDetailForAdminPanel(orderId: number, shopIds: Types.ObjectId[]) {
return this.model.aggregate([
{
$match: {
order: orderId,
shop: { $in: shopIds },
},
},
{
$lookup: {
from: "orders",
localField: "order",
foreignField: "_id",
as: "order",
},
},
{
$unwind: "$order",
},
{
$lookup: {
from: "cartpayments",
localField: "order.payment",
foreignField: "_id",
as: "order.payment",
},
},
{
$unwind: "$order.payment",
},
{
$lookup: {
from: "paymentmethods",
localField: "order.payment.payment_method",
foreignField: "_id",
as: "order.payment.payment_method",
},
},
{
$unwind: "$order.payment.payment_method",
},
{
$lookup: {
from: "users",
localField: "order.user",
foreignField: "_id",
as: "order.user",
},
},
{
$unwind: "$order.user",
},
{
$unwind: "$shipmentItems",
},
{
$lookup: {
from: "products",
localField: "shipmentItems.product",
foreignField: "_id",
as: "shipmentItems.product",
},
},
{
$unwind: "$shipmentItems.product",
},
{
$lookup: {
from: "productvariants",
localField: "shipmentItems.variant",
foreignField: "_id",
as: "shipmentItems.variant",
},
},
{
$unwind: "$shipmentItems.variant",
},
{
$lookup: {
from: "warranties",
localField: "shipmentItems.variant.warranty",
foreignField: "_id",
as: "shipmentItems.variant.warranty",
},
},
{
$unwind: {
path: "$shipmentItems.variant.warranty",
preserveNullAndEmptyArrays: true,
},
},
{
$lookup: {
from: "colors",
localField: "shipmentItems.variant.color",
foreignField: "_id",
as: "shipmentItems.variant.color",
},
},
{
$unwind: {
path: "$shipmentItems.variant.color",
preserveNullAndEmptyArrays: true,
},
},
{
$lookup: {
from: "sizes",
localField: "shipmentItems.variant.size",
foreignField: "_id",
as: "shipmentItems.variant.size",
},
},
{
$unwind: {
path: "$shipmentItems.variant.size",
preserveNullAndEmptyArrays: true,
},
},
{
$lookup: {
from: "meterages",
localField: "shipmentItems.variant.meterage",
foreignField: "_id",
as: "shipmentItems.variant.meterage",
},
},
{
$unwind: {
path: "$shipmentItems.variant.meterage",
preserveNullAndEmptyArrays: true,
},
},
{
$lookup: {
from: "shipments",
localField: "shipper",
foreignField: "_id",
as: "shipper",
},
},
{
$unwind: "$shipper",
},
{
$group: {
_id: "$order._id",
user: { $first: "$order.user" },
payment: { $first: "$order.payment" },
shipmentAddress: { $first: "$order.shipmentAddress" },
orderStatus: { $first: "$order.orderStatus" },
createdAt: { $first: "$order.createdAt" },
orderItems: {
$first: {
_id: "$_id",
order_id: "$order._id",
shop: "$shop",
shipper: "$shipper",
totalSellingPrice: "$totalSellingPrice",
totalRetailPrice: "$totalRetailPrice",
totalShipmentCost: "$totalShipmentCost",
totalPaymentPrice: "$totalPaymentPrice",
itemsCount: "$itemsCount",
trackCode: "$trackCode",
postingDate: "$postingDate",
postingReceipt: "$postingReceipt",
status: "$status",
},
},
shipmentItems: {
$push: {
_id: "$shipmentItems._id",
product: "$shipmentItems.product",
variant: "$shipmentItems.variant",
quantity: "$shipmentItems.quantity",
cancelled_quantity: "$shipmentItems.cancelled_quantity",
returned_quantity: "$shipmentItems.returned_quantity",
selling_price: "$shipmentItems.selling_price",
retail_price: "$shipmentItems.retail_price",
discount_percent: "$shipmentItems.discount_percent",
shipmentCost: "$shipmentItems.shipmentCost",
},
},
// totalSellingPrice: { $sum: { $multiply: ["$shipmentItems.selling_price", "$shipmentItems.quantity"] } },
// totalRetailPrice: { $sum: { $multiply: ["$shipmentItems.retail_price", "$shipmentItems.quantity"] } },
// totalShipmentCost: { $sum: "$shipmentItems.shipmentCost" },
// itemsCount: { $sum: "$shipmentItems.quantity" },
},
},
{
$addFields: {
"orderItems.shipmentItems": "$shipmentItems",
// totalPaymentPrice: { $add: ["$totalSellingPrice", "$totalShipmentCost"] },
},
},
]);
}
async getSellerSalesStats(shopId: string, queries: { start?: string; end?: string }) {
// Parse the date range from queries, converting from Persian to Gregorian if necessary
const startDate = queries.start ? new Date(TimeService.convertPersianToGregorian(queries.start)) : null;
+47
View File
@@ -322,6 +322,29 @@ class OrderService {
}
//#######################################################
//#######################################################
async getAdminUserOrderDetail(orderId: number) {
const { order } = await this.validateAdminUserOrder(orderId);
const doc = await this.orderRepo.getUserOrderDetail(orderId, order.user._id.toString());
const cleanedOrder = SellerOrdersDTO.transformOrder(doc[0]);
return { order: cleanedOrder };
}
//#######################################################
//#######################################################
async getAdminSellerOrderDetail(orderId: number) {
const { shopIds } = await this.validateAdminSellerOrder(orderId);
const doc = await this.orderItemRepo.getSellerOrderDetailForAdminPanel(orderId, shopIds);
const cleanedOrder = SellerOrdersDTO.transformOrder(doc[0]);
return { order: cleanedOrder };
}
//#######################################################
//#######################################################
async getSellerSalesStats(sellerId: string, queries: { start: string; end: string }) {
const shop = await this.shopRepo.model.findOne({ owner: sellerId });
if (!shop) throw new BadRequestError(ShopMessage.ShopNotFound);
@@ -365,6 +388,30 @@ class OrderService {
return { order, orderItems };
}
//#######################################################
//#######################################################
private async validateAdminUserOrder(orderId: number) {
const order = await this.orderRepo.model.findOne({ _id: orderId });
if (!order) throw new BadRequestError(OrderMessage.NotFound);
const orderItems = await this.orderItemRepo.model.find({ order: order._id });
if (!orderItems || orderItems.length === 0) throw new BadRequestError(OrderMessage.OrderItemsNotFound);
return { order, orderItems };
}
//#######################################################
//#######################################################
private async validateAdminSellerOrder(orderId: number) {
const order = await this.orderRepo.model.findOne({ _id: orderId }).lean();
if (!order) throw new BadRequestError(OrderMessage.NotFound);
const orderItems = await this.orderItemRepo.model.find({ order: orderId }).lean();
const shopIds = orderItems.map((item) => item.shop._id);
const orderItem = await this.orderItemRepo.model.findOne({ shop: { in: shopIds }, order: order._id });
if (!orderItem) throw new BadRequestError(OrderMessage.OrderItemsNotFound);
return { order, orderItem, shopIds };
}
//#######################################
//#######################################