narinder1231 commited on
Commit
27423e4
·
1 Parent(s): 72c33c1

add filter, sorting and pagination on list invoices

Browse files
src/controllers/invoice/invoice.controller.ts CHANGED
@@ -6,6 +6,7 @@ import FormData from "form-data";
6
  import Invoice from "../../models/invoice";
7
  import InvoiceDetail from "../../models/invoicedetail";
8
  import User from "../../models/users";
 
9
 
10
  export const createInvoice = async (req: Request, res: Response) => {
11
  const files = req.files as Express.Multer.File[];
@@ -81,20 +82,122 @@ export const createInvoice = async (req: Request, res: Response) => {
81
  }
82
  };
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  // Get All Invoices
85
  export const getAllInvoices = async (req: Request, res: Response): Promise<Response> => {
86
  try {
87
- const invoices = await Invoice.findAll({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  include: [
89
  { model: User, as: 'uploadedBy' }
90
  ]
91
- });
 
 
 
 
 
 
 
 
 
92
 
93
  if (invoices.length === 0) {
94
  return res.status(404).json({ error: "No invoices found" });
95
  }
96
 
97
- return res.status(200).json(invoices);
98
  } catch (error) {
99
  console.error("Error fetching invoices:", error);
100
  return res.status(500).json({ error: "Error fetching invoices" });
 
6
  import Invoice from "../../models/invoice";
7
  import InvoiceDetail from "../../models/invoicedetail";
8
  import User from "../../models/users";
9
+ import { FindOptions, Op } from "sequelize";
10
 
11
  export const createInvoice = async (req: Request, res: Response) => {
12
  const files = req.files as Express.Multer.File[];
 
82
  }
83
  };
84
 
85
+ const buildInvoiceWhereClause = (filter: Record<string, any>): any => {
86
+ const whereClause: any = {};
87
+
88
+ if (filter) {
89
+ if (filter.vendor_name) {
90
+ whereClause.vendor_name = { [Op.like]: `%${filter.vendor_name}%` };
91
+ }
92
+
93
+ if (filter.reference_number) {
94
+ whereClause.reference_number = { [Op.like]: `%${filter.reference_number}%` };
95
+ }
96
+
97
+ if (filter.invoice_date) {
98
+ const date = new Date(filter.invoice_date);
99
+ if (!isNaN(date.getTime())) {
100
+ whereClause.invoice_date = { [Op.eq]: date };
101
+ }
102
+ }
103
+
104
+ if (filter.uploaded_by) {
105
+ whereClause.uploaded_by = { [Op.eq]: filter.uploaded_by };
106
+ }
107
+
108
+ if (filter.due_date) {
109
+ const date = new Date(filter.due_date);
110
+ if (!isNaN(date.getTime())) {
111
+ whereClause.due_date = { [Op.eq]: date };
112
+ }
113
+ }
114
+
115
+ if (filter.payment_status) {
116
+ whereClause.payment_status = { [Op.eq]: filter.payment_status };
117
+ }
118
+
119
+ if (filter.status) {
120
+ whereClause.status = { [Op.eq]: filter.status };
121
+ }
122
+
123
+ if (filter.pw_work_order_id) {
124
+ whereClause.pw_work_order_id = { [Op.eq]: filter.pw_work_order_id };
125
+ }
126
+
127
+ if (filter.created_before) {
128
+ const beforeDate = new Date(filter.created_before);
129
+ if (!isNaN(beforeDate.getTime())) {
130
+ whereClause.created_at = { ...whereClause.created_at, [Op.lte]: beforeDate };
131
+ }
132
+ }
133
+
134
+ if (filter.created_after) {
135
+ const afterDate = new Date(filter.created_after);
136
+ if (!isNaN(afterDate.getTime())) {
137
+ whereClause.created_at = { ...whereClause.created_at, [Op.gte]: afterDate };
138
+ }
139
+ }
140
+ }
141
+
142
+ return whereClause;
143
+ };
144
+
145
  // Get All Invoices
146
  export const getAllInvoices = async (req: Request, res: Response): Promise<Response> => {
147
  try {
148
+ const { sort_by, sort_order, page, limit } = req.query;
149
+ const filter = req.query.filter as Record<string, any>;
150
+
151
+ const allowedSortColumns = [
152
+ 'id',
153
+ 'invoice_date',
154
+ 'total',
155
+ 'amount_paid',
156
+ 'due_date',
157
+ 'pw_work_order_id',
158
+ 'pw_vendor_id',
159
+ 'uploaded_by',
160
+ ];
161
+
162
+ const whereClause = buildInvoiceWhereClause(filter);
163
+
164
+ const currentPage = parseInt(page as string) || 1;
165
+ const pageSize = parseInt(limit as string) || 10;
166
+
167
+ const options: FindOptions = {
168
+ where: whereClause,
169
+ limit: pageSize,
170
+ offset: (currentPage - 1) * pageSize,
171
+ order: []
172
+ };
173
+
174
+ if (sort_by && allowedSortColumns.includes(sort_by as string)) {
175
+ options.order = [[sort_by as string, sort_order === 'desc' ? 'DESC' : 'ASC']];
176
+ } else {
177
+ options.order = [['id', 'ASC']];
178
+ }
179
+
180
+ const [invoices, totalInvoices] = await Promise.all([
181
+ Invoice.findAll({...options,
182
  include: [
183
  { model: User, as: 'uploadedBy' }
184
  ]
185
+ }),
186
+ Invoice.count({ where: whereClause }),
187
+ ]);
188
+
189
+ const data = {
190
+ page: currentPage,
191
+ limit: pageSize,
192
+ total: totalInvoices,
193
+ invoices: invoices
194
+ };
195
 
196
  if (invoices.length === 0) {
197
  return res.status(404).json({ error: "No invoices found" });
198
  }
199
 
200
+ return res.status(200).json(data);
201
  } catch (error) {
202
  console.error("Error fetching invoices:", error);
203
  return res.status(500).json({ error: "Error fetching invoices" });