From 164951321ba06184b80dd7f53ed58b9e62a39d67 Mon Sep 17 00:00:00 2001 From: Md Sharafat Hassain Binoy Date: Fri, 17 Apr 2026 01:59:58 +0600 Subject: [PATCH 1/3] order Api: implement the searching system --- package.json | 2 +- src/app/modules/order/order.service.ts | 51 ++++++++++++++++++++++- src/app/modules/order/order.swagger.ts | 18 ++++++++ src/app/modules/order/order.validation.ts | 9 ---- 4 files changed, 69 insertions(+), 11 deletions(-) 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.service.ts b/src/app/modules/order/order.service.ts index 371301b..c9c11b8 100644 --- a/src/app/modules/order/order.service.ts +++ b/src/app/modules/order/order.service.ts @@ -6,7 +6,55 @@ import { orderEmailQueue } from "../../queues/email/order/order.email.queue"; const get_all_order_from_db = async (req: Request) => { // define your own login here - const result = await prisma.order.findMany(); + const search=req.query.search as string + const customerName=req.query.customerName as string + const productName=req.query.productName as string + console.log(productName) + 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" + } + } + ] + }) + } + + console.log(search) + + const result = await prisma.order.findMany({ + where:{ + AND:andCondition + } + }); return result; }; @@ -19,6 +67,7 @@ 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" diff --git a/src/app/modules/order/order.swagger.ts b/src/app/modules/order/order.swagger.ts index f0e2f4d..103de00 100644 --- a/src/app/modules/order/order.swagger.ts +++ b/src/app/modules/order/order.swagger.ts @@ -45,6 +45,24 @@ 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" }, + }, ], responses: { 200: { description: "order fetched successfully" }, 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() }); From 1bc1fae274c4097bfeb0efdb3311347f49900195 Mon Sep 17 00:00:00 2001 From: Md Sharafat Hassain Binoy Date: Fri, 17 Apr 2026 23:36:01 +0600 Subject: [PATCH 2/3] order api:implement pagination system --- src/app/modules/order/order.service.ts | 137 +++++++++++++++---------- src/app/modules/order/order.swagger.ts | 45 ++++---- src/app/utils/pagination_helper.ts | 34 ++++++ 3 files changed, 142 insertions(+), 74 deletions(-) create mode 100644 src/app/utils/pagination_helper.ts diff --git a/src/app/modules/order/order.service.ts b/src/app/modules/order/order.service.ts index c9c11b8..3063531 100644 --- a/src/app/modules/order/order.service.ts +++ b/src/app/modules/order/order.service.ts @@ -1,61 +1,92 @@ - import { Request } from "express"; import { configs } from "../../configs"; import { prisma } from "../../lib/prisma"; import { orderEmailQueue } from "../../queues/email/order/order.email.queue"; +import paginationHelper from "../../utils/pagination_helper"; const get_all_order_from_db = async (req: Request) => { // define your own login here - const search=req.query.search as string - const customerName=req.query.customerName as string - const productName=req.query.productName as string - console.log(productName) - 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" - } - } - ] - }) - } - - console.log(search) + const search = req.query.search as string; + const customerName = req.query.customerName as string; + const productName = req.query.productName as string; + const status = (req.query.status as string) || undefined; + const { page, limit, skip, sortBy, sortOrder } = paginationHelper(req.query); - const result = await prisma.order.findMany({ - where:{ - AND:andCondition - } + 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", + }, + }, + ], + }); + } + + const getAllOrders = await prisma.order.findMany({ + take: limit, + skip, + where: { + AND: andCondition, + }, + orderBy: { + [sortBy as string]: sortOrder, + }, }); - return result; + const result = await prisma.order.count({ + where: { + AND: andCondition, + }, + }); + console.log(status); + return { + data: getAllOrders, + pagination: { + total: result, + page, + limit, + totalPages: Math.ceil(result / limit), + }, + }; }; const get_single_order_from_db = async (req: Request) => { @@ -67,9 +98,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) + console.log(payload); payload.status = "INITIATED"; - payload.paymentType = "COD" + payload.paymentType = "COD"; // nwo init order const result = await prisma.order.create({ data: payload }); @@ -81,8 +112,8 @@ 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; }; diff --git a/src/app/modules/order/order.swagger.ts b/src/app/modules/order/order.swagger.ts index 103de00..927705d 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", + }), }, }, }, @@ -63,6 +62,12 @@ export const orderSwaggerDocs = { required: false, schema: { type: "string" }, }, + { + name: "status", + in: "query", + required: false, + schema: { type: "string" }, + }, ], responses: { 200: { description: "order fetched successfully" }, @@ -106,14 +111,14 @@ 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" + shopAccountId: "", + productPrice: 1500, + productQuantity: 2, + productName: "Wireless Mouse", + customerName: "Rahim Uddin", + customerPhone: "+8801712345678", + customerAddress: "Rangpur, Bangladesh", + customerNote: "Please deliver between 3-5 PM", }), // put your request body }, }, @@ -142,5 +147,3 @@ export const orderSwaggerDocs = { }, }, }; - - 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 From 4c1614601ad17b3060d34975875b68e2c8d743a5 Mon Sep 17 00:00:00 2001 From: Md Sharafat Hassain Binoy Date: Sun, 19 Apr 2026 00:26:50 +0600 Subject: [PATCH 3/3] Order API:All routes was created and fully tested --- src/app/modules/order/order.route.ts | 3 ++- src/app/modules/order/order.service.ts | 35 +++++++++++++++++++++++++- src/app/modules/order/order.swagger.ts | 29 +++++++++++++++------ 3 files changed, 57 insertions(+), 10 deletions(-) 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 3063531..0b492fe 100644 --- a/src/app/modules/order/order.service.ts +++ b/src/app/modules/order/order.service.ts @@ -2,6 +2,7 @@ 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) => { @@ -9,6 +10,12 @@ const get_all_order_from_db = async (req: Request) => { 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); @@ -62,6 +69,24 @@ const get_all_order_from_db = async (req: Request) => { }); } + // 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, @@ -77,7 +102,6 @@ const get_all_order_from_db = async (req: Request) => { AND: andCondition, }, }); - console.log(status); return { data: getAllOrders, pagination: { @@ -120,7 +144,16 @@ const create_order_into_db = async (req: Request) => { 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 927705d..d17fd4a 100644 --- a/src/app/modules/order/order.swagger.ts +++ b/src/app/modules/order/order.swagger.ts @@ -68,6 +68,26 @@ export const orderSwaggerDocs = { 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" }, @@ -111,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 }, },