add : complete return order

This commit is contained in:
morteza-mortezai
2025-11-01 15:31:59 +03:30
parent 024f3cb3a2
commit 599d2ad992
5 changed files with 60 additions and 6 deletions
@@ -4,16 +4,18 @@ import { controller, httpDelete, httpGet, httpPost, queryParam, request, request
import { HttpStatus } from "../../../common";
import { BaseController } from "../../../common/base/controller";
import { ApiAuth, ApiModel, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from "../../../common/decorator/swggerDocs";
import { ApiAuth, ApiFile, ApiModel, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from "../../../common/decorator/swggerDocs";
import { PaginationDTO } from "../../../common/dto/pagination.dto";
import { Guard } from "../../../core/middlewares/guard.middleware";
import { ValidationMiddleware } from "../../../core/middlewares/validator.middleware";
import { IOCTYPES } from "../../../IOC/ioc.types";
import { UploadService } from "../../../utils/upload.service";
import { CancelService } from "../../cancel/cancel.service";
import { CreateCancelDTO } from "../../cancel/DTO/cancel.dto";
import { CancelReasonDTO } from "../../cancel/DTO/cancelReason.dto";
import { Gran } from "../../order/order.repository";
import { OrderService } from "../../order/order.service";
import { CompeleteReturnRequestDTO } from "../../return/DTO/return.dto";
import { ReasonDTO, UpdateReasonDTO } from "../../return/DTO/returnReason.dto";
import { ReturnService } from "../../return/return.service";
import { OwnerRef } from "../../shop/models/Abstraction/IShop";
@@ -76,10 +78,11 @@ export class AdminOrderController extends BaseController {
@ApiOperation("complete a return order request with return order id")
@ApiResponse("successful", HttpStatus.Ok)
@ApiParam("returnOrderId", "id of return order", true)
@ApiModel(CompeleteReturnRequestDTO)
@ApiAuth()
@httpPost("/returns/:returnOrderId/complete", Guard.authAdmin(), Guard.checkAdminPermissions([PermissionEnum.ORDER]))
public async completeReturnRequest(@requestParam("returnOrderId") returnOrderId: string) {
const data = await this.returnService.completeReturnRequest(returnOrderId);
public async completeReturnRequest(@requestParam("returnOrderId") returnOrderId: string, @requestBody() dto: CompeleteReturnRequestDTO) {
const data = await this.returnService.completeReturnRequest(returnOrderId, dto);
return this.response(data);
}
@@ -283,4 +286,23 @@ export class AdminOrderController extends BaseController {
const data = await this.orderService.getSaleOrderChart(granularity, from, to);
return this.response(data);
}
//uploader
@ApiOperation("Upload a return refund receipt info image ")
@ApiResponse("File uploaded successfully", HttpStatus.Accepted)
@ApiFile("image")
@ApiAuth()
@httpPost("/image/upload", Guard.authAdmin(), UploadService.single("image", "shipping-receipt"))
public async uploadImage(@request() req: Request) {
const file = req.file as Express.MulterS3.File;
const data = {
message: "file uploaded!",
url: {
size: file?.size,
url: file?.location,
type: file?.mimetype,
},
};
return this.response({ data }, HttpStatus.Accepted);
}
}
+21
View File
@@ -128,3 +128,24 @@ export class ReturnRequestDTO {
})
items: ReturnRequestItemsDTO[];
}
export class CompeleteReturnRequestDTO {
@Expose()
@IsNotEmpty()
@IsString()
@ApiProperty({ type: "string", description: "Date", example: "1404/02/02" })
refundDate: string;
@Expose()
@IsNotEmpty()
@IsString()
@ApiProperty({ type: "string", description: "comment", example: "متن دلخواه" })
refundComment: string;
@Expose()
@IsOptional()
@IsNotEmpty()
@IsString()
@ApiProperty({ type: "string", description: "the image of recept if mandatory ", example: "https://cdn.com" })
refundReceipt?: string;
}
@@ -7,4 +7,7 @@ export interface IReturnOrder {
user: Types.ObjectId;
status: StatusEnum;
total_price: number;
refundReceipt: string;
refundDate: Date;
refundComment: string;
}
@@ -9,6 +9,9 @@ const ReturnOrderSchema = new Schema<IReturnOrder>(
user: { type: Schema.Types.ObjectId, ref: "User", required: true },
status: { type: String, enum: StatusEnum, default: StatusEnum.Pending },
total_price: { type: Number, default: 0 },
refundReceipt: { type: String, default: null },
refundComment: { type: String, default: null },
refundDate: { type: Date, default: null },
},
{ timestamps: true, toJSON: { versionKey: false, virtuals: true }, id: false },
);
+8 -3
View File
@@ -1,7 +1,7 @@
import { inject, injectable } from "inversify";
import { isValidObjectId, startSession } from "mongoose";
import { ReturnOrderDTO, ReturnRequestDTO } from "./DTO/return.dto";
import { CompeleteReturnRequestDTO, ReturnOrderDTO, ReturnRequestDTO } from "./DTO/return.dto";
import { ReasonDTO, UpdateReasonDTO } from "./DTO/returnReason.dto";
import { ReturnOrderItemRepo, ReturnOrderRepo, ReturnReasonRepo } from "./return.repository";
import { PaginationDTO } from "../../common/dto/pagination.dto";
@@ -192,12 +192,17 @@ class ReturnService {
//#######################################################
//#######################################################
async completeReturnRequest(returnOrderId: string) {
async completeReturnRequest(returnOrderId: string, dto: CompeleteReturnRequestDTO) {
const session = await startSession();
session.startTransaction();
const { refundComment, refundDate, refundReceipt } = dto;
try {
// update returnOrder status to 'completed'
const returnOrder = await this.returnOrderRepo.model.findByIdAndUpdate(returnOrderId, { status: StatusEnum.Completed }, { session });
const returnOrder = await this.returnOrderRepo.model.findByIdAndUpdate(
returnOrderId,
{ status: StatusEnum.Completed, refundComment, refundDate, refundReceipt },
{ session },
);
if (!returnOrder) throw new BadRequestError(OrderMessage.ReturnOrderNotFound);
// Fetch ReturnOrderItems