add search and pagination on users, units, products, category

pull/1/head
Aji Kamaludin 3 years ago
parent 3061611745
commit 68a19eb1a7
No known key found for this signature in database
GPG Key ID: 670E1F26AD5A8099

@ -22,8 +22,8 @@
"pm.test('test is ok!', () => {",
" const responseJson = pm.response.json();",
"",
" pm.expect(responseJson).to.haveOwnProperty('status');",
" pm.expect(responseJson.status).to.equals('Ok!');",
" pm.expect(responseJson).to.haveOwnProperty('data');",
" pm.expect(responseJson.data.status).to.equals('Ok!');",
" // pm.environment.get('songId')",
" pm.environment.set('status', responseJson.status);",
"})"
@ -403,7 +403,7 @@
"method": "GET",
"header": [],
"url": {
"raw": "{{host}}/users?startDate={{currentdate}}&endDate={{futuredate}}",
"raw": "{{host}}/users?q=e&p=1",
"host": [
"{{host}}"
],
@ -412,12 +412,12 @@
],
"query": [
{
"key": "startDate",
"value": "{{currentdate}}"
"key": "q",
"value": "e"
},
{
"key": "endDate",
"value": "{{futuredate}}"
"key": "p",
"value": "1"
}
]
}
@ -690,7 +690,7 @@
"method": "GET",
"header": [],
"url": {
"raw": "{{host}}/units?startDate={{currentdate}}&endDate={{futuredate}}",
"raw": "{{host}}/units?q=e&page=1",
"host": [
"{{host}}"
],
@ -699,12 +699,12 @@
],
"query": [
{
"key": "startDate",
"value": "{{currentdate}}"
"key": "q",
"value": "e"
},
{
"key": "endDate",
"value": "{{futuredate}}"
"key": "page",
"value": "1"
}
]
}
@ -977,7 +977,7 @@
"method": "GET",
"header": [],
"url": {
"raw": "{{host}}/categories?startDate={{currentdate}}&endDate={{futuredate}}",
"raw": "{{host}}/categories?page=1&q=m",
"host": [
"{{host}}"
],
@ -986,12 +986,12 @@
],
"query": [
{
"key": "startDate",
"value": "{{currentdate}}"
"key": "page",
"value": "1"
},
{
"key": "endDate",
"value": "{{futuredate}}"
"key": "q",
"value": "m"
}
]
}
@ -1292,7 +1292,7 @@
"method": "GET",
"header": [],
"url": {
"raw": "{{host}}/products?startDate={{currentdate}}&endDate={{futuredate}}&withStock=true",
"raw": "{{host}}/products?page=1&q=e&withStock=true",
"host": [
"{{host}}"
],
@ -1301,12 +1301,12 @@
],
"query": [
{
"key": "startDate",
"value": "{{currentdate}}"
"key": "page",
"value": "1"
},
{
"key": "endDate",
"value": "{{futuredate}}"
"key": "q",
"value": "e"
},
{
"key": "withStock",

@ -39,14 +39,12 @@ class CategoriesHandler {
async getCategoriesHandler(request) {
try {
const { companyId } = request.auth.credentials;
const { startDate, endDate } = request.query;
const categories = await this._service.getCategories(companyId, { startDate, endDate });
const { page, q } = request.query;
const { categories, meta } = await this._service.getCategories(companyId, { page, q });
return {
status: 'success',
data: {
categories,
},
data: { categories, meta },
};
} catch (error) {
return error;

@ -40,17 +40,17 @@ class ProductsHandler {
async getProductsHandler(request) {
try {
this._validator.validateGetProductsPayload(request.query);
const { companyId } = request.auth.credentials;
const { startDate, endDate, withStock } = request.query;
const products = await this._service.getProducts(companyId, {
startDate, endDate, withStock,
const { page, q, withStock } = request.query;
const { products, meta } = await this._service.getProducts(companyId, {
page, q, withStock,
});
return {
status: 'success',
data: {
products,
meta,
},
};
} catch (error) {

@ -36,13 +36,14 @@ class UnitsHandler {
async getUnitsHandler(request) {
try {
const { companyId } = request.auth.credentials;
const { startDate, endDate } = request.query;
const units = await this._service.getUnits(companyId, { startDate, endDate });
const { page, q } = request.query;
const { units, meta } = await this._service.getUnits(companyId, { page, q });
return {
status: 'success',
data: {
units,
meta,
},
};
} catch (error) {

@ -29,11 +29,11 @@ const routes = (handler) => [
validate: {
validator: Joi,
query: {
startDate: Joi.date().required(),
endDate: Joi.date().required(),
page: Joi.string().allow(''),
q: Joi.string().allow(''),
},
failAction: () => {
throw new InvariantError('startDate and endDate is required');
throw new InvariantError('params is required');
},
},
},

@ -12,15 +12,15 @@ class UsersHandler {
async getUsersHandler(request) {
try {
this._validator.validateGetUsersPayload(request.query);
const { companyId } = request.auth.credentials;
const { startDate, endDate } = request.query;
const users = await this._service.getUsers(companyId, { startDate, endDate });
const { page, q } = request.query;
const { users, meta } = await this._service.getUsers(companyId, { page, q });
return {
status: 'success',
data: {
users,
meta,
},
};
} catch (error) {

@ -8,15 +8,40 @@ class CategoriesService {
this._pool = new Pool();
}
async getCategories(companyId, { startDate, endDate }) {
async getCategories(companyId, { page = 1, limit = 10, q = null }) {
const recordsQuery = await this._pool.query(`
SELECT count(id) as total
FROM categories
WHERE
company_id = '${companyId}'
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
`);
const { total } = recordsQuery.rows[0];
const totalPages = Math.ceil(total / limit);
const offsets = limit * (page - 1);
const query = {
text: 'SELECT id, name, description FROM categories WHERE company_id = $1 AND created_at::DATE BETWEEN $2 AND $3',
values: [companyId, startDate, endDate],
text: `
SELECT id, name, description
FROM categories
WHERE company_id = $1
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
LIMIT $2 OFFSET $3`,
values: [companyId, limit, offsets],
};
const results = await this._pool.query(query);
const { rows } = await this._pool.query(query);
return results.rows;
return {
categories: rows,
meta: {
totalPages,
total,
page,
},
};
}
async getCategoryById(categoryId) {

@ -9,13 +9,30 @@ class ProductsService {
this._pool = new Pool();
}
async getProducts(companyId, { startDate, endDate, withStock }) {
async getProducts(companyId, {
page = 1, q = null, withStock, limit = 10,
}) {
const recordsQuery = await this._pool.query(`
SELECT count(id) as total
FROM products
WHERE
company_id = '${companyId}'
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
`);
const { total } = recordsQuery.rows[0];
const totalPages = Math.ceil(total / limit);
const offsets = limit * (page - 1);
let query = {
text: `SELECT
id, name, description, price, cost
FROM products
WHERE company_id = $1 AND created_at::DATE BETWEEN $2 AND $3`,
values: [companyId, startDate, endDate],
WHERE company_id = $1
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
LIMIT $2 OFFSET $3`,
values: [companyId, limit, offsets],
};
if (withStock && withStock === 'true') {
@ -24,14 +41,23 @@ class ProductsService {
name, description, price, cost, stock
FROM products
LEFT JOIN stocks ON stocks.product_id = products.id
WHERE company_id = $1 AND products.created_at BETWEEN $2 AND $3`,
values: [companyId, startDate, endDate],
WHERE company_id = $1
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
LIMIT $2 OFFSET $3`,
values: [companyId, limit, offsets],
};
}
const results = await this._pool.query(query);
const { rows } = await this._pool.query(query);
return results.rows;
return {
products: rows,
meta: {
totalPages,
total,
page,
},
};
}
async getProductById({ productId, companyId }) {

@ -8,15 +8,38 @@ class UnitsService {
this._pool = new Pool();
}
async getUnits(companyId, { startDate, endDate }) {
async getUnits(companyId, { page = 1, q = null, limit = 10 }) {
const recordsQuery = await this._pool.query(`
SELECT count(id) as total
FROM units
WHERE
company_id = '${companyId}'
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
`);
const { total } = recordsQuery.rows[0];
const totalPages = Math.ceil(total / limit);
const offsets = limit * (page - 1);
const query = {
text: 'SELECT id, name, description FROM units WHERE company_id = $1 AND created_at::DATE BETWEEN $2 AND $3',
values: [companyId, startDate, endDate],
text: `
SELECT id, name, description FROM units WHERE company_id = $1
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
LIMIT $2 OFFSET $3`,
values: [companyId, limit, offsets],
};
const results = await this._pool.query(query);
const { rows } = await this._pool.query(query);
return results.rows;
return {
units: rows,
meta: {
totalPages,
total,
page,
},
};
}
async getUnitById(unitId) {

@ -63,16 +63,38 @@ class UsersService {
return id;
}
async getUsers(companyId, { startDate, endDate }) {
// TODO: implement pagination leter
async getUsers(companyId, { page = 1, q = null, limit = 10 }) {
const recordsQuery = await this._pool.query(`
SELECT count(id) as total
FROM users
WHERE
company_id = '${companyId}'
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
`);
const { total } = recordsQuery.rows[0];
const totalPages = Math.ceil(total / limit);
const offsets = limit * (page - 1);
const query = {
text: 'SELECT name, email, role FROM users WHERE company_id = $1 AND created_at::DATE BETWEEN $2 AND $3',
values: [companyId, startDate, endDate],
text: `
SELECT name, email, role FROM users WHERE company_id = $1
${q !== null ? `AND name ILIKE '%${q}%'` : ''}
LIMIT $2 OFFSET $3`,
values: [companyId, limit, offsets],
};
const result = await this._pool.query(query);
const { rows } = await this._pool.query(query);
return result.rows;
return {
users: rows,
meta: {
totalPages,
total,
page,
},
};
}
async getUserById({ userId, companyId }) {

@ -1,4 +1,4 @@
const { PostProductPayloadSchema, PutProductPayloadSchema, GetProductsPayloadSchema } = require('./schema');
const { PostProductPayloadSchema, PutProductPayloadSchema } = require('./schema');
const InvariantError = require('../../exceptions/InvariantError');
const ProductsValidator = {
@ -14,12 +14,6 @@ const ProductsValidator = {
throw new InvariantError(validationResult.error.message);
}
},
validateGetProductsPayload: (payload) => {
const validationResult = GetProductsPayloadSchema.validate(payload);
if (validationResult.error) {
throw new InvariantError(validationResult.error.message);
}
},
};
module.exports = ProductsValidator;

@ -18,10 +18,4 @@ const PutProductPayloadSchema = Joi.object({
category_id: Joi.string().guid().required(),
});
const GetProductsPayloadSchema = Joi.object({
startDate: Joi.date().required(),
endDate: Joi.date().required(),
withStock: Joi.boolean().allow(''),
});
module.exports = { PostProductPayloadSchema, PutProductPayloadSchema, GetProductsPayloadSchema };
module.exports = { PostProductPayloadSchema, PutProductPayloadSchema };

@ -1,4 +1,4 @@
const { PostUserPayloadSchema, PutUserPayloadSchema, GetUsersPayloadSchema } = require('./schema');
const { PostUserPayloadSchema, PutUserPayloadSchema } = require('./schema');
const InvariantError = require('../../exceptions/InvariantError');
const UsersValidator = {
@ -14,12 +14,6 @@ const UsersValidator = {
throw new InvariantError(validationResult.error.message);
}
},
validateGetUsersPayload: (payload) => {
const validationResult = GetUsersPayloadSchema.validate(payload);
if (validationResult.error) {
throw new InvariantError(validationResult.error.message);
}
},
};
module.exports = UsersValidator;

@ -12,9 +12,4 @@ const PutUserPayloadSchema = Joi.object({
password: Joi.string().allow(''),
});
const GetUsersPayloadSchema = Joi.object({
startDate: Joi.date().required(),
endDate: Joi.date().required(),
});
module.exports = { PostUserPayloadSchema, PutUserPayloadSchema, GetUsersPayloadSchema };
module.exports = { PostUserPayloadSchema, PutUserPayloadSchema };

Loading…
Cancel
Save