add customer end point , update sales to more detail
parent
97a5cb21d9
commit
09bfda51c7
Binary file not shown.
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 155 KiB |
@ -0,0 +1,105 @@
|
|||||||
|
class CustomersHandler {
|
||||||
|
constructor(service, validator) {
|
||||||
|
this._service = service;
|
||||||
|
this._validator = validator;
|
||||||
|
|
||||||
|
this.postCustomerHandler = this.postCustomerHandler.bind(this);
|
||||||
|
this.getCustomersHandler = this.getCustomersHandler.bind(this);
|
||||||
|
this.getCustomerByIdHandler = this.getCustomerByIdHandler.bind(this);
|
||||||
|
this.putCustomerByIdHandler = this.putCustomerByIdHandler.bind(this);
|
||||||
|
this.deleteCustomerByIdHandler = this.deleteCustomerByIdHandler.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
async postCustomerHandler(request, h) {
|
||||||
|
try {
|
||||||
|
this._validator.validatePostCustomerPayload(request.payload);
|
||||||
|
|
||||||
|
const { companyId } = request.auth.credentials;
|
||||||
|
const { name, phone, address, description } = request.payload;
|
||||||
|
|
||||||
|
const customerId = await this._service.addCustomer({
|
||||||
|
name, phone, address, description, companyId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = h.response({
|
||||||
|
status: 'success',
|
||||||
|
message: 'Customer berhasil ditambahkan',
|
||||||
|
data: {
|
||||||
|
customerId,
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
response.code(201);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCustomersHandler(request) {
|
||||||
|
try {
|
||||||
|
const { companyId } = request.auth.credentials;
|
||||||
|
const { page, q } = request.query;
|
||||||
|
const { customers, meta } = await this._service.getCustomers(companyId, { page, q });
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
data: { customers, meta },
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCustomerByIdHandler(request) {
|
||||||
|
try {
|
||||||
|
const { id: customerId } = request.params;
|
||||||
|
const customer = await this._service.getCustomerById(customerId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
data: {
|
||||||
|
customer,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async putCustomerByIdHandler(request) {
|
||||||
|
try {
|
||||||
|
this._validator.validatePostCustomerPayload(request.payload);
|
||||||
|
const { id: customerId } = request.params;
|
||||||
|
const { name, phone, address, description } = request.payload;
|
||||||
|
|
||||||
|
await this._service.updateCustomerById(customerId, { name, phone, address, description });
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteCustomerByIdHandler(request) {
|
||||||
|
try {
|
||||||
|
const { id: customerId } = request.params;
|
||||||
|
|
||||||
|
await this._service.deleteCustomerById(customerId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
data: {},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CustomersHandler;
|
@ -0,0 +1,11 @@
|
|||||||
|
const CustomersHandler = require('./handler');
|
||||||
|
const routes = require('./routes');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'customers',
|
||||||
|
version: '1.0.0',
|
||||||
|
register: async (server, { service, validator }) => {
|
||||||
|
const customersHandler = new CustomersHandler(service, validator);
|
||||||
|
server.route(routes(customersHandler));
|
||||||
|
},
|
||||||
|
};
|
@ -0,0 +1,44 @@
|
|||||||
|
const routes = (handler) => [
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
path: '/customers',
|
||||||
|
handler: handler.postCustomerHandler,
|
||||||
|
options: {
|
||||||
|
auth: 'kasiraja_jwt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/customers',
|
||||||
|
handler: handler.getCustomersHandler,
|
||||||
|
options: {
|
||||||
|
auth: 'kasiraja_jwt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/customers/{id}',
|
||||||
|
handler: handler.getCustomerByIdHandler,
|
||||||
|
options: {
|
||||||
|
auth: 'kasiraja_jwt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
path: '/customers/{id}',
|
||||||
|
handler: handler.putCustomerByIdHandler,
|
||||||
|
options: {
|
||||||
|
auth: 'kasiraja_jwt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'DELETE',
|
||||||
|
path: '/customers/{id}',
|
||||||
|
handler: handler.deleteCustomerByIdHandler,
|
||||||
|
options: {
|
||||||
|
auth: 'kasiraja_jwt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = routes;
|
@ -0,0 +1,100 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const uuid = require('uuid-random');
|
||||||
|
const NotFoundError = require('../../exceptions/NotFoundError');
|
||||||
|
const { validateUuid } = require('../../utils');
|
||||||
|
|
||||||
|
class CustomersService {
|
||||||
|
constructor() {
|
||||||
|
this._pool = new Pool();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCustomers(companyId, { page = 1, limit = 10, q = null }) {
|
||||||
|
const recordsQuery = await this._pool.query(`
|
||||||
|
SELECT count(id) as total
|
||||||
|
FROM customers
|
||||||
|
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, phone, description
|
||||||
|
FROM customers
|
||||||
|
WHERE company_id = $1
|
||||||
|
${q !== null ? `AND name ILIKE '%${q}%' OR phone ILIKE '%${q}%'` : ''}
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT $2 OFFSET $3`,
|
||||||
|
values: [companyId, limit, offsets],
|
||||||
|
};
|
||||||
|
|
||||||
|
const { rows } = await this._pool.query(query);
|
||||||
|
|
||||||
|
return {
|
||||||
|
customers: rows,
|
||||||
|
meta: {
|
||||||
|
totalPages,
|
||||||
|
total,
|
||||||
|
page,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCustomerById(customerId) {
|
||||||
|
validateUuid(customerId);
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
text: 'SELECT name, phone, address, description FROM customers WHERE id = $1',
|
||||||
|
values: [customerId],
|
||||||
|
};
|
||||||
|
|
||||||
|
const results = await this._pool.query(query);
|
||||||
|
|
||||||
|
if (results.rowCount < 1) {
|
||||||
|
throw new NotFoundError('Customer tidak ditemukan');
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.rows[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
async addCustomer({ name, phone, address, description, companyId }) {
|
||||||
|
const id = uuid();
|
||||||
|
const query = {
|
||||||
|
text: 'INSERT INTO customers(id, name, phone, address, description, company_id) VALUES ($1, $2, $3, $4, $5, $6)',
|
||||||
|
values: [id, name, phone, address, description, companyId],
|
||||||
|
};
|
||||||
|
|
||||||
|
await this._pool.query(query);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateCustomerById(customerId, { name, phone, address, description }) {
|
||||||
|
validateUuid(customerId);
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
text: 'UPDATE customers SET name = $1, phone = $2, address = $3, description = $4 WHERE id = $5',
|
||||||
|
values: [name, phone, address, description, customerId],
|
||||||
|
};
|
||||||
|
|
||||||
|
await this._pool.query(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteCustomerById(customerId) {
|
||||||
|
validateUuid(customerId);
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
text: 'DELETE FROM customers WHERE id = $1',
|
||||||
|
values: [customerId],
|
||||||
|
};
|
||||||
|
|
||||||
|
await this._pool.query(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CustomersService;
|
@ -0,0 +1,13 @@
|
|||||||
|
const PostCustomerPayloadSchema = require('./schema');
|
||||||
|
const InvariantError = require('../../exceptions/InvariantError');
|
||||||
|
|
||||||
|
const CustomerValidator = {
|
||||||
|
validatePostCustomerPayload: (payload) => {
|
||||||
|
const validationResult = PostCustomerPayloadSchema.validate(payload);
|
||||||
|
if (validationResult.error) {
|
||||||
|
throw new InvariantError(validationResult.error.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = CustomerValidator;
|
@ -0,0 +1,10 @@
|
|||||||
|
const Joi = require('joi');
|
||||||
|
|
||||||
|
const PostCustomerPayloadSchema = Joi.object({
|
||||||
|
name: Joi.string().required(),
|
||||||
|
phone: Joi.string().allow(''),
|
||||||
|
address: Joi.string().allow(''),
|
||||||
|
description: Joi.string().allow(''),
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = PostCustomerPayloadSchema;
|
Loading…
Reference in New Issue