diff --git a/package.json b/package.json index f4b3d6c..8d527f7 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@types/express": "^5.0.3", "@types/jsonwebtoken": "^9.0.10", "@types/multer": "^2.0.0", - "@types/node": "^24.10.9", + "@types/node": "^24.12.2", "@types/nodemailer": "^7.0.2", "@types/pg": "^8.20.0", "@types/swagger-jsdoc": "^6.0.4", diff --git a/src/app/modules/order/order.route.ts b/src/app/modules/order/order.route.ts index d0d162e..d002096 100644 --- a/src/app/modules/order/order.route.ts +++ b/src/app/modules/order/order.route.ts @@ -3,6 +3,7 @@ import RequestValidator from "../../middlewares/request_validator"; import { order_controller } from "./order.controller"; import { order_validations } from "./order.validation"; +import auth from "../../middlewares/auth"; const router = Router(); @@ -14,7 +15,7 @@ router.post( ); router.get("/:id", order_controller.get_single_order); router.patch( - "/:id", + "/:id",auth("ADMIN"), RequestValidator(order_validations.update_order), order_controller.update_order, ); diff --git a/src/app/modules/order/order.service.ts b/src/app/modules/order/order.service.ts index 371301b..0b492fe 100644 --- a/src/app/modules/order/order.service.ts +++ b/src/app/modules/order/order.service.ts @@ -1,13 +1,116 @@ - import { Request } from "express"; import { configs } from "../../configs"; import { prisma } from "../../lib/prisma"; import { orderEmailQueue } from "../../queues/email/order/order.email.queue"; +import { AppError } from "../../utils/app_error"; +import paginationHelper from "../../utils/pagination_helper"; const get_all_order_from_db = async (req: Request) => { // define your own login here - const result = await prisma.order.findMany(); - return result; + const search = req.query.search as string; + const customerName = req.query.customerName as string; + const productName = req.query.productName as string; + + // for date filter + + const startDate = req.query.startDate as string; + const endDate = req.query.endDate as string; + + const status = (req.query.status as string) || undefined; + const { page, limit, skip, sortBy, sortOrder } = paginationHelper(req.query); + + const andCondition = [] as any[]; + if (search) { + andCondition.push({ + OR: [ + { + productName: { + contains: search, + mode: "insensitive", + }, + }, + ], + }); + } + if (customerName) { + andCondition.push({ + OR: [ + { + customerName: { + contains: customerName, + mode: "insensitive", + }, + }, + ], + }); + } + if (productName) { + andCondition.push({ + OR: [ + { + productName: { + contains: productName, + mode: "insensitive", + }, + }, + ], + }); + } + if (status) { + andCondition.push({ + OR: [ + { + status: { + contains: status, + mode: "insensitive", + }, + }, + ], + }); + } + + // for date filter + const dateFilter: any = {}; + if (startDate) { + const start = new Date(startDate); + start.setHours(0, 0, 0, 0); + dateFilter.gte = start; + } + if (endDate) { + const end = new Date(endDate); + end.setHours(23, 59, 59, 999); + dateFilter.lte = end; + } + if (Object.keys(dateFilter).length > 0) { + andCondition.push({ + createdAt: dateFilter, + }); + } + + const getAllOrders = await prisma.order.findMany({ + take: limit, + skip, + where: { + AND: andCondition, + }, + orderBy: { + [sortBy as string]: sortOrder, + }, + }); + const result = await prisma.order.count({ + where: { + AND: andCondition, + }, + }); + return { + data: getAllOrders, + pagination: { + total: result, + page, + limit, + totalPages: Math.ceil(result / limit), + }, + }; }; const get_single_order_from_db = async (req: Request) => { @@ -19,8 +122,9 @@ const get_single_order_from_db = async (req: Request) => { const create_order_into_db = async (req: Request) => { const payload = req?.body; + console.log(payload); payload.status = "INITIATED"; - payload.paymentType = "COD" + payload.paymentType = "COD"; // nwo init order const result = await prisma.order.create({ data: payload }); @@ -32,15 +136,24 @@ const create_order_into_db = async (req: Request) => { email: payload.customerEmail, subject: "Order Tracking", textBody: `Your order has been created. Track your order here: ${trackingLink}`, - htmlBody: `
Your order has been created. Track your order here: Track Order
` - }) + htmlBody: `Your order has been created. Track your order here: Track Order
`, + }); } return result; }; const update_order_into_db = async (req: Request) => { // define your own login here + const user = req.user; + console.log(user); + if (user?.role !== "ADMIN") { + throw new AppError("You are not authorized to perform this action", 403); + } const { id } = req.params as { id: string }; + const isProductExist = await prisma.order.findUnique({ where: { id } }); + if (!isProductExist) { + throw new AppError("Order is not found", 404); + } const result = await prisma.order.update({ where: { id }, data: req.body }); return result; }; diff --git a/src/app/modules/order/order.swagger.ts b/src/app/modules/order/order.swagger.ts index f0e2f4d..d17fd4a 100644 --- a/src/app/modules/order/order.swagger.ts +++ b/src/app/modules/order/order.swagger.ts @@ -1,4 +1,3 @@ - export const orderSwaggerDocs = { "/api/order": { post: { @@ -10,16 +9,16 @@ export const orderSwaggerDocs = { content: { "application/json": { example: JSON.stringify({ - "shopAccountId": "", - "productPrice": 1500, - "productQuantity": 2, - "productName": "Wireless Mouse", - "customerName": "Rahim Uddin", - "customerPhone": "+8801712345678", - "customerEmail": "softvence.abumahid@gmail.com", - "customerAddress": "Rangpur, Bangladesh", - "customerNote": "Please deliver between 3-5 PM" - }) + shopAccountId: "", + productPrice: 1500, + productQuantity: 2, + productName: "Wireless Mouse", + customerName: "Rahim Uddin", + customerPhone: "+8801712345678", + customerEmail: "softvence.abumahid@gmail.com", + customerAddress: "Rangpur, Bangladesh", + customerNote: "Please deliver between 3-5 PM", + }), }, }, }, @@ -45,6 +44,50 @@ export const orderSwaggerDocs = { required: false, schema: { type: "number" }, }, + { + name: "search", + in: "query", + required: false, + schema: { type: "string" }, + }, + { + name: "customerName", + in: "query", + required: false, + schema: { type: "string" }, + }, + { + name: "productName", + in: "query", + required: false, + schema: { type: "string" }, + }, + { + name: "status", + in: "query", + required: false, + schema: { type: "string" }, + }, + { + name: "date", + in: "query", + required: false, + schema: { type: "string" }, + }, + { + name: "startDate", + in: "query", + required: false, + schema: { type: "string", format: "date" }, + example: "2026-04-01", + }, + { + name: "endDate", + in: "query", + required: false, + schema: { type: "string", format: "date" }, + example: "2026-04-31", + }, ], responses: { 200: { description: "order fetched successfully" }, @@ -88,14 +131,7 @@ export const orderSwaggerDocs = { content: { "application/json": { example: JSON.stringify({ - "shopAccountId": "", - "productPrice": 1500, - "productQuantity": 2, - "productName": "Wireless Mouse", - "customerName": "Rahim Uddin", - "customerPhone": "+8801712345678", - "customerAddress": "Rangpur, Bangladesh", - "customerNote": "Please deliver between 3-5 PM" + status: "INITIATED", }), // put your request body }, }, @@ -124,5 +160,3 @@ export const orderSwaggerDocs = { }, }, }; - - diff --git a/src/app/modules/order/order.validation.ts b/src/app/modules/order/order.validation.ts index 114c4ff..e3a08aa 100644 --- a/src/app/modules/order/order.validation.ts +++ b/src/app/modules/order/order.validation.ts @@ -13,15 +13,6 @@ const create_order = z.object({ customerNote: z.string().optional() }); const update_order = z.object({ - shopAccountId: z.string().optional(), - productPrice: z.number().optional(), - productQuantity: z.number().optional(), - productName: z.string().optional(), - customerName: z.string().optional(), - customerPhone: z.string().optional(), - customerEmail: z.string().optional(), - customerAddress: z.string().optional(), - customerNote: z.string().optional(), status: z.string().optional() }); diff --git a/src/app/utils/pagination_helper.ts b/src/app/utils/pagination_helper.ts new file mode 100644 index 0000000..9ed373f --- /dev/null +++ b/src/app/utils/pagination_helper.ts @@ -0,0 +1,34 @@ +// options type +type IOptions = { + page?: number | string; + limit?: number | string; + sortOrder?: string; + sortBy?: string; +}; + +// return type +export type IPaginationResult = { + page: number; + limit: number; + skip: number; + sortOrder?: string; + sortBy?: string; +}; +const paginationHelper = (options:IOptions): IPaginationResult => { + const page = Number(options?.page) || 1; + const limit = Number(options?.limit) || 10; + const skip = (page-1)*limit + const sortBy =options?.sortBy ||"createdAt"; + const sortOrder = options?.sortOrder || "desc"; + + return { + page, + limit, + skip, + sortBy, + sortOrder + } +}; + + +export default paginationHelper; \ No newline at end of file