Compare commits
4 Commits
ec65f155b2
...
45e07d6413
| Author | SHA1 | Date | |
|---|---|---|---|
| 45e07d6413 | |||
|
|
c6604703fe | ||
|
|
d39f5f129e | ||
| a1d326aa40 |
@@ -5,10 +5,14 @@ export const DB_USER_ERROR = 'USER';
|
|||||||
|
|
||||||
let currentDate = (new Date()).toISOString().slice(0, 10);
|
let currentDate = (new Date()).toISOString().slice(0, 10);
|
||||||
|
|
||||||
export async function getCurrentDate() {
|
export function getCurrentDate() {
|
||||||
return currentDate;
|
return currentDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Random_Increase() {
|
||||||
|
return Math.floor(Math.random() * 5) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
export async function setCurrentDate(newDate) {
|
export async function setCurrentDate(newDate) {
|
||||||
currentDate = newDate;
|
currentDate = newDate;
|
||||||
console.log(`📅 Date changed to: ${currentDate}`);
|
console.log(`📅 Date changed to: ${currentDate}`);
|
||||||
@@ -62,6 +66,24 @@ export default class DBAdapter {
|
|||||||
console.log("DISCONNECT");
|
console.log("DISCONNECT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async stock(){
|
||||||
|
try {
|
||||||
|
const products = await this.#dbClient.query('SELECT id FROM products');
|
||||||
|
for (const product of products) {
|
||||||
|
const increment = Random_Increase();
|
||||||
|
await this.#dbClient.query('UPDATE products SET quantity = quantity + ? WHERE id = ?', [
|
||||||
|
increment,
|
||||||
|
product.id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (err){
|
||||||
|
return Promise.reject({
|
||||||
|
type: err
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getProducts() {
|
async getProducts() {
|
||||||
try {
|
try {
|
||||||
const products = await this.#dbClient.query('SELECT * FROM products ORDER BY name');
|
const products = await this.#dbClient.query('SELECT * FROM products ORDER BY name');
|
||||||
@@ -144,7 +166,7 @@ export default class DBAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteOrdersByIds(orderIds) {
|
async clearOrders(orderIds) {
|
||||||
if (!orderIds || orderIds.length === 0) {
|
if (!orderIds || orderIds.length === 0) {
|
||||||
console.log("No orders to delete");
|
console.log("No orders to delete");
|
||||||
return;
|
return;
|
||||||
@@ -165,4 +187,215 @@ export default class DBAdapter {
|
|||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
async changeOrderInfo({ id, customer_name, orderDate }){
|
||||||
|
if (!id) {
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Order ID is required")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentDate = await getCurrentDate();
|
||||||
|
if (orderDate < currentDate) {
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Order date cannot be less than current date")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const order = await this.#dbClient.query('SELECT * FROM orders WHERE id = ?', [id]);
|
||||||
|
|
||||||
|
if (!order){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Order not found")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedName = customer_name;
|
||||||
|
const updatedDate = orderDate;
|
||||||
|
|
||||||
|
await this.#dbClient.query('UPDATE orders SET customer_name = ?, order_date = ? WHERE id = ?',
|
||||||
|
[updatedName, updatedDate, id]
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch(err){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_INTERNAL_ERROR,
|
||||||
|
error: new Error("Server error")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteOrderById(order_id){
|
||||||
|
try {
|
||||||
|
const orderItems = await this.#dbClient.query(
|
||||||
|
`SELECT product_id, quantity FROM order_items WHERE order_id = ?`,
|
||||||
|
[order_id]
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const item of orderItems){
|
||||||
|
await this.#dbClient.query('UPDATE products SET quantity = quantity + ? WHERE id = ?',
|
||||||
|
[item.quantity, item.product_id]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await this.#dbClient.query(
|
||||||
|
`DELETE FROM orders WHERE id = ?`,
|
||||||
|
[order_id]
|
||||||
|
);
|
||||||
|
} catch(err){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_INTERNAL_ERROR,
|
||||||
|
error: new Error("Server error")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async addOrderItem({ orderId, productId, quantity }){
|
||||||
|
await this.#dbClient.query('BEGIN');
|
||||||
|
try {
|
||||||
|
const product = await this.#dbClient.query(
|
||||||
|
'SELECT quantity FROM products WHERE id = ?', [productId]
|
||||||
|
);
|
||||||
|
|
||||||
|
const productRow = product?.[0];
|
||||||
|
if (!productRow || productRow.quantity < quantity){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Insufficient product quantity")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await this.#dbClient.query(
|
||||||
|
'INSERT INTO order_items (order_id, product_id, quantity) VALUES (?, ?, ?)',
|
||||||
|
[orderId, productId, quantity]
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.#dbClient.query(
|
||||||
|
'UPDATE products SET quantity = quantity - ? WHERE id = ?',
|
||||||
|
[quantity, productId]
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.#dbClient.query('COMMIT');
|
||||||
|
} catch (err){
|
||||||
|
await this.#dbClient.query('ROLLBACK');
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateOrderItem({ itemId, quantity }){
|
||||||
|
await this.#dbClient.query('BEGIN');
|
||||||
|
try {
|
||||||
|
const item = await this.#dbClient.query(
|
||||||
|
'SELECT product_id, quantity FROM order_items WHERE id = ?', [itemId]
|
||||||
|
);
|
||||||
|
|
||||||
|
const itemRow = item?.[0];
|
||||||
|
if (!itemRow){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Order item not found")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const diff = quantity - itemRow.quantity;
|
||||||
|
|
||||||
|
if (diff > 0){
|
||||||
|
const product = await this.#dbClient.query(
|
||||||
|
'SELECT quantity FROM products WHERE id = ?', [itemRow.product_id]
|
||||||
|
);
|
||||||
|
|
||||||
|
const productRow = product?.[0];
|
||||||
|
if (!productRow || productRow.quantity < diff){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Insufficient product quantity")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.#dbClient.query(
|
||||||
|
'UPDATE products SET quantity = quantity - ? WHERE id = ?',
|
||||||
|
[diff, itemRow.product_id]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff < 0) {
|
||||||
|
await this.#dbClient.query(
|
||||||
|
'UPDATE products SET quantity = quantity + ? WHERE id = ?',
|
||||||
|
[-diff, itemRow.product_id]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.#dbClient.query(
|
||||||
|
'UPDATE order_items SET quantity = ? WHERE id = ?',
|
||||||
|
[quantity, itemId]
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.#dbClient.query('COMMIT');
|
||||||
|
} catch (err){
|
||||||
|
await this.#dbClient.query('ROLLBACK');
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteOrderItem(itemId){
|
||||||
|
await this.#dbClient.query('BEGIN');
|
||||||
|
try {
|
||||||
|
const item = await this.#dbClient.query(
|
||||||
|
'SELECT product_id, quantity FROM order_items WHERE id = ?', [itemId]
|
||||||
|
);
|
||||||
|
|
||||||
|
const itemRow = item?.[0];
|
||||||
|
if (!itemRow){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Order item not found")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.#dbClient.query(
|
||||||
|
'UPDATE products SET quantity = quantity + ? WHERE id = ?',
|
||||||
|
[itemRow.quantity, itemRow.product_id]
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.#dbClient.query(
|
||||||
|
'DELETE FROM order_items WHERE id = ?',
|
||||||
|
[itemId]
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.#dbClient.query('COMMIT');
|
||||||
|
} catch (err){
|
||||||
|
await this.#dbClient.query('ROLLBACK');
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async moveOrderItem( {itemId, targetOrderId }){
|
||||||
|
await this.#dbClient.query('BEGIN');
|
||||||
|
try {
|
||||||
|
const item = await this.#dbClient.query(
|
||||||
|
'SELECT id, order_id FROM order_items WHERE id = ?', [itemId]
|
||||||
|
);
|
||||||
|
|
||||||
|
const itemRow = item?.[0];
|
||||||
|
if (!itemRow){
|
||||||
|
return Promise.reject({
|
||||||
|
type: DB_USER_ERROR,
|
||||||
|
error: new Error("Order item not found")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.#dbClient.query(
|
||||||
|
'UPDATE order_items SET order_id = ? WHERE id = ?',
|
||||||
|
[targetOrderId, itemId]
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.#dbClient.query('COMMIT');
|
||||||
|
} catch (err){
|
||||||
|
await this.#dbClient.query('ROLLBACK');
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
137
server/server.js
137
server/server.js
@@ -16,6 +16,8 @@ const {
|
|||||||
PASSWORD
|
PASSWORD
|
||||||
} = process.env;
|
} = process.env;
|
||||||
|
|
||||||
|
const appPort = 3000;
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
@@ -33,12 +35,8 @@ function AddDays(dateString, days) {
|
|||||||
return date.toISOString().slice(0, 10);
|
return date.toISOString().slice(0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Random_Increase() {
|
|
||||||
return Math.floor(Math.random() * 5) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.get('/api/current-date', async (req, res) => {
|
app.get('/api/current-date', async (req, res) => {
|
||||||
let currentDate = await getCurrentDate();
|
let currentDate = getCurrentDate();
|
||||||
res.json({ currentDate });
|
res.json({ currentDate });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -68,13 +66,15 @@ app.get('/api/products', async(req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.post('/api/current-date/advance', async (req, res) => {
|
app.post('/api/current-date/advance', async (req, res) => {
|
||||||
let currentDate = await getCurrentDate();
|
let currentDate = getCurrentDate();
|
||||||
try {
|
try {
|
||||||
const raw_ids = await adapter.getOrdersByDate(currentDate);
|
const raw_ids = await adapter.getOrdersByDate(currentDate);
|
||||||
const ids = raw_ids.map(item => item.id);
|
if (raw_ids && raw_ids.length > 0) {
|
||||||
await adapter.deleteOrdersByIds(ids);
|
const ids = raw_ids.map(item => item.id);
|
||||||
|
await adapter.clearOrders(ids);
|
||||||
|
}
|
||||||
let nextDate = AddDays(currentDate, 1);
|
let nextDate = AddDays(currentDate, 1);
|
||||||
|
await adapter.stock();
|
||||||
await setCurrentDate(nextDate);
|
await setCurrentDate(nextDate);
|
||||||
res.json({ currentDate: nextDate });
|
res.json({ currentDate: nextDate });
|
||||||
} catch (err){
|
} catch (err){
|
||||||
@@ -82,7 +82,7 @@ app.post('/api/current-date/advance', async (req, res) => {
|
|||||||
res.message = "WHOOPS";
|
res.message = "WHOOPS";
|
||||||
res.json({
|
res.json({
|
||||||
timeStamp: new Date().toISOString(),
|
timeStamp: new Date().toISOString(),
|
||||||
statusCode: 500,
|
statusCode: res.statusCode,
|
||||||
error : `${err}`
|
error : `${err}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -170,15 +170,122 @@ app.post('/api/orders', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.delete('/api/orders/:id', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await adapter.deleteOrderById(req.params.id);
|
||||||
|
res.statusCode = 200;
|
||||||
|
res.message = "OK";
|
||||||
|
res.json({message: "success"});
|
||||||
|
} catch (err){
|
||||||
|
res.statusCode = 500;
|
||||||
|
res.message = "WHOOPS";
|
||||||
|
res.json({
|
||||||
|
timeStamp: new Date().toISOString(),
|
||||||
|
statusCode: 500,
|
||||||
|
error: `${err}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post('/api/orders/:orderId/items', async (req, res) => {
|
||||||
|
let orderId = req.params.orderId;
|
||||||
|
let { productId, quantity } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await adapter.addOrderItem({
|
||||||
|
orderId,
|
||||||
|
productId,
|
||||||
|
quantity
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(201).json({
|
||||||
|
orderId,
|
||||||
|
productId,
|
||||||
|
quantity
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
// TODO
|
||||||
|
res.status(500).json({
|
||||||
|
timeStamp: new Date().toISOString(),
|
||||||
|
statusCode: 500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.put('/api/orders/:orderId/items/:itemId', async (req, res) => {
|
||||||
|
let itemId = req.params.itemId;
|
||||||
|
let quantity = req.body.quantity;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await adapter.updateOrderItem({
|
||||||
|
itemId,
|
||||||
|
quantity
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(201).json({
|
||||||
|
itemId,
|
||||||
|
quantity
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
// TODO
|
||||||
|
res.status(500).json({
|
||||||
|
timeStamp: new Date().toISOString(),
|
||||||
|
statusCode: 500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete('/api/orders/:orderId/items/:itemId', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await adapter.deleteOrderItem(req.params.itemId);
|
||||||
|
res.status(204).end();
|
||||||
|
} catch (err){
|
||||||
|
res.statusCode = 500;
|
||||||
|
res.message = "WHOOPS";
|
||||||
|
res.json({
|
||||||
|
timeStamp: new Date().toISOString(),
|
||||||
|
statusCode: 500,
|
||||||
|
error: `${err}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post('/api/order-items/:itemId/move', async (req, res) => {
|
||||||
|
let itemId = req.params.itemId;
|
||||||
|
let targetOrderId = req.body.targetOrderId;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await adapter.moveOrderItem({
|
||||||
|
itemId,
|
||||||
|
targetOrderId,
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(201).json({
|
||||||
|
itemId,
|
||||||
|
targetOrderId,
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
// TODO
|
||||||
|
res.status(500).json({
|
||||||
|
timeStamp: new Date().toISOString(),
|
||||||
|
statusCode: 500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
res.status(404).json({ error: 'Invalid route' });
|
res.status(404).json({ error: 'Invalid route' });
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(3000, async() => {
|
const server = app.listen(appPort, async() => {
|
||||||
try {
|
try {
|
||||||
await adapter.connect();
|
await adapter.connect();
|
||||||
console.log(`✅ Server running on port 3000`);
|
console.log(`✅ Server running on port ${appPort}`);
|
||||||
console.log(`📡 Local: http://localhost:3000`);
|
console.log(`📡 Local: http://localhost:${appPort}`);
|
||||||
} catch(err){
|
} catch(err){
|
||||||
console.log("Shutting down application...");
|
console.log("Shutting down application...");
|
||||||
process.exit(100);
|
process.exit(100);
|
||||||
@@ -187,8 +294,8 @@ app.listen(3000, async() => {
|
|||||||
|
|
||||||
process.on('SIGTERM', () => {
|
process.on('SIGTERM', () => {
|
||||||
console.log("CLOSE APP");
|
console.log("CLOSE APP");
|
||||||
app.close( async() => {
|
server.close(async () => {
|
||||||
await adapter.disconnect();
|
await adapter.disconnect();
|
||||||
console.log("DB DISCONNECTED");
|
console.log("DB DISCONNECTED");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user