Adding Order cancellation request

This commit is contained in:
sairajzero 2021-09-02 21:24:11 +05:30
parent a7a2c22622
commit 9443ac5d51
5 changed files with 270 additions and 78 deletions

View File

@ -84,7 +84,7 @@ function signUp(privKey, sid) {
}).then(result => responseParse(result, false) }).then(result => responseParse(result, false)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error))) .catch(error => reject(error)))
.catch(error => console.error(error)); .catch(error => reject(error));
}) })
} }
@ -109,7 +109,7 @@ function login(privKey, sid, rememberMe = false) {
}).then(result => responseParse(result, false) }).then(result => responseParse(result, false)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error))) .catch(error => reject(error)))
.catch(error => console.error(error)); .catch(error => reject(error));
}) })
} }
@ -126,9 +126,9 @@ function logout() {
function buy(quantity, max_price) { function buy(quantity, max_price) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= 0) if (typeof quantity !== "number" || quantity <= 0)
return reject(INVALID(`Invalid quantity (${quantity})`)); return reject(`Invalid quantity (${quantity})`);
else if (typeof max_price !== "number" || max_price <= 0) else if (typeof max_price !== "number" || max_price <= 0)
return reject(INVALID(`Invalid max_price (${max_price})`)); return reject(`Invalid max_price (${max_price})`);
fetch('/buy', { fetch('/buy', {
method: "POST", method: "POST",
headers: { headers: {
@ -141,7 +141,7 @@ function buy(quantity, max_price) {
}).then(result => responseParse(result, false) }).then(result => responseParse(result, false)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error))) .catch(error => reject(error)))
.catch(error => console.error(error)) .catch(error => reject(error))
}) })
} }
@ -149,9 +149,9 @@ function buy(quantity, max_price) {
function sell(quantity, min_price) { function sell(quantity, min_price) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= 0) if (typeof quantity !== "number" || quantity <= 0)
return reject(INVALID(`Invalid quantity (${quantity})`)); return reject(`Invalid quantity (${quantity})`);
else if (typeof min_price !== "number" || min_price <= 0) else if (typeof min_price !== "number" || min_price <= 0)
return reject(INVALID(`Invalid min_price (${min_price})`)); return reject(`Invalid min_price (${min_price})`);
fetch('/sell', { fetch('/sell', {
method: "POST", method: "POST",
headers: { headers: {
@ -164,7 +164,27 @@ function sell(quantity, min_price) {
}).then(result => responseParse(result, false) }).then(result => responseParse(result, false)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error))) .catch(error => reject(error)))
.catch(error => console.error(error)) .catch(error => reject(error))
}) })
}
function cancelOrder(type, id) {
return new Promise((resolve, reject) => {
if (type !== "buy" && type !== "sell")
return reject(`Invalid type (${type}): type should be sell (or) buy`);
fetch('/cancel', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
orderType: type,
orderID: id
})
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
} }

View File

@ -23,82 +23,147 @@
</form> </form>
<div id="user-container"> <div id="user-container">
<fieldset> <fieldset>
<legend>User</legend> <legend>Profile</legend>
<span id="user_id"></span><br /> <span id="user_id"></span><br />
FLO: <span id="flo_bal"></span><br /> FLO: <span id="flo_bal"></span><br />
Rupee: <span id="rupee_bal"></span><br /> Rupee: <span id="rupee_bal"></span><br />
<button onclick="UI_evt.logout();">logout</button> <button onclick="UI_evt.logout();">logout</button>
</fieldset> <form id="buy-form">
<form id="buy-form"> <fieldset>
<fieldset> <legend>Buy</legend>
<legend>Buy</legend> <input type="number" name="quantity" placeholder="Enter Quantity" />
<input type="number" name="quantity" placeholder="Enter Quantity" /> <input type="number" name="max-price" placeholder="Enter Max Price" />
<input type="number" name="max-price" placeholder="Enter Max Price" /> <input type="button" name="buy" value="buy" onclick="UI_evt.buy();" />
<input type="button" name="buy" value="buy" onclick="UI_evt.buy();" /> </fieldset>
</fieldset> </form>
</form> <form id="sell-form">
<form id="sell-form"> <fieldset>
<fieldset> <legend>Sell</legend>
<legend>Sell</legend> <input type="number" name="quantity" placeholder="Enter Quantity" />
<input type="number" name="quantity" placeholder="Enter Quantity" /> <input type="number" name="min-price" placeholder="Enter Min Price" />
<input type="number" name="min-price" placeholder="Enter Min Price" /> <input type="button" name="sell" value="sell" onclick="UI_evt.sell();" />
<input type="button" name="sell" value="sell" onclick="UI_evt.sell();" /> </fieldset>
</fieldset> </form>
</form> <button onclick="toggle_view('my-profile');">Toggle</button>
</div> <div id="my-profile">
<div id="buy-orders"> <div id="my-orders">
<fieldset> <fieldset>
<legend>BuyOrders</legend> <legend>My Orders</legend>
<table> <fieldset id="my-buy-orders">
<thead> <legend>Buying</legend>
<tr> <table>
<th>Buyer</th> <thead>
<th>Quantity</th> <tr>
<th>Max Price</th> <th>Select</th>
<th>Order Placed</th> <th>Quantity</th>
</tr> <th>Max Price</th>
</thead> <th>Order Placed</th>
<tbody></tbody> </tr>
</table> </thead>
</fieldset> <tbody data-type="buy"></tbody>
</div> </table>
<div id="sell-orders"> </fieldset>
<fieldset> <fieldset id="my-sell-orders">
<legend>SellOrders</legend> <legend>Selling</legend>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Seller</th> <th>Select</th>
<th>Quantity</th> <th>Quantity</th>
<th>Min Price</th> <th>Min Price</th>
<th>Order Placed</th> <th>Order Placed</th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody data-type="sell"></tbody>
</table> </table>
</fieldset> </fieldset>
</div> <button name="cancel-orders" onclick="UI_evt.cancelOrders();">Cancel Orders</button>
<div id="transactions"> </fieldset>
<fieldset>
<legend>transactions</legend>
<table>
<thead>
<tr>
<th>Seller</th>
<th>Buyer</th>
<th>Quantity</th>
<th>Unit Value</th>
<th>Time</th>
</tr>
</thead>
<tbody></tbody>
</table>
</fieldset>
</div>
<button onclick="refresh();">refresh</button> </div>
<div id="my-transactions">
<fieldset>
<legend>My Transactions</legend>
<table>
<thead>
<tr>
<th>Sold/Brought</th>
<th>To/From</th>
<th>Quantity</th>
<th>Unit Value</th>
<th>Time</th>
</tr>
</thead>
<tbody></tbody>
</table>
</fieldset>
</div>
</div>
</fieldset>
</div>
<button onclick="toggle_view('all-container');">Toggle All</button>
<button onclick="refresh();">Refresh</button>
<div id="all-container">
<div id="buy-orders">
<fieldset>
<legend>BuyOrders</legend>
<table>
<thead>
<tr>
<th>Buyer</th>
<th>Quantity</th>
<th>Max Price</th>
<th>Order Placed</th>
</tr>
</thead>
<tbody></tbody>
</table>
</fieldset>
</div>
<div id="sell-orders">
<fieldset>
<legend>SellOrders</legend>
<table>
<thead>
<tr>
<th>Seller</th>
<th>Quantity</th>
<th>Min Price</th>
<th>Order Placed</th>
</tr>
</thead>
<tbody></tbody>
</table>
</fieldset>
</div>
<div id="transactions">
<fieldset>
<legend>Transactions</legend>
<table>
<thead>
<tr>
<th>Seller</th>
<th>Buyer</th>
<th>Quantity</th>
<th>Unit Value</th>
<th>Time</th>
</tr>
</thead>
<tbody></tbody>
</table>
</fieldset>
</div>
</div>
<script> <script>
function toggle_view(id) {
let element = document.getElementById(id)
if (element.style.display === "none")
element.style.display = "block";
else
element.style.display = "none";
}
function list_buy() { function list_buy() {
getBuyList().then(list => { getBuyList().then(list => {
let container = document.getElementById("buy-orders").getElementsByTagName("tbody")[0]; let container = document.getElementById("buy-orders").getElementsByTagName("tbody")[0];
@ -154,19 +219,65 @@
function account() { function account() {
getAccount().then(acc => { getAccount().then(acc => {
console.debug(acc); console.debug(acc);
//Element display
document.getElementById("login-form").style.display = "none"; document.getElementById("login-form").style.display = "none";
document.getElementById('user-container').style.display = "block"; document.getElementById('user-container').style.display = "block";
document.getElementById("user_id").textContent = acc.floID; document.getElementById("user_id").textContent = acc.floID;
//FLO Balance
let flo_total = acc.coins.reduce((a, x) => a + x.quantity, 0); let flo_total = acc.coins.reduce((a, x) => a + x.quantity, 0);
let flo_locked = acc.sellOrders.reduce((a, x) => a + x.quantity, 0); let flo_locked = acc.sellOrders.reduce((a, x) => a + x.quantity, 0);
let flo_net = flo_total - flo_locked; let flo_net = flo_total - flo_locked;
console.debug("FLO", flo_total, flo_locked, flo_net); console.debug("FLO", flo_total, flo_locked, flo_net);
document.getElementById("flo_bal").textContent = flo_net + "(+" + flo_locked + ")"; document.getElementById("flo_bal").textContent = flo_net + "(+" + flo_locked + ")";
//Rupee Balance
let rupee_total = acc.rupee_total; let rupee_total = acc.rupee_total;
let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0); let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0);
let rupee_net = rupee_total - rupee_locked; let rupee_net = rupee_total - rupee_locked;
console.debug("RUPEE", rupee_total, rupee_locked, rupee_net); console.debug("RUPEE", rupee_total, rupee_locked, rupee_net);
document.getElementById("rupee_bal").textContent = rupee_net + "(+" + rupee_locked + ")"; document.getElementById("rupee_bal").textContent = rupee_net + "(+" + rupee_locked + ")";
//My buy orders
let container = document.getElementById("my-buy-orders").getElementsByTagName("tbody")[0];
container.innerHTML = '';
acc.buyOrders.forEach(o => {
let row = container.insertRow();
row.insertCell().innerHTML = `<input type="checkbox">`;
row.insertCell().textContent = o.quantity;
row.insertCell().textContent = o.maxPrice;
row.insertCell().textContent = new Date(o.time_placed);
row.dataset["id"] = o.id;
});
//My sell orders
container = document.getElementById("my-sell-orders").getElementsByTagName("tbody")[0];
container.innerHTML = '';
acc.sellOrders.forEach(o => {
let row = container.insertRow();
row.insertCell().innerHTML = `<input type="checkbox">`;
row.insertCell().textContent = o.quantity;
row.insertCell().textContent = o.minPrice;
row.insertCell().textContent = new Date(o.time_placed);
row.dataset["id"] = o.id;
});
//My Transactions
container = document.getElementById("my-transactions").getElementsByTagName("tbody")[0];
container.innerHTML = '';
acc.transactions.forEach(o => {
let type, other;
if (o.seller === acc.floID) {
type = 'Sold To';
other = o.buyer === acc.floID ? 'MySelf' : o.buyer;
} else if (o.buyer === acc.floID) {
type = 'Brought From';
other = o.seller;
} else
return;
let row = container.insertRow();
row.insertCell().textContent = type;
row.insertCell().textContent = other;
row.insertCell().textContent = o.quantity;
row.insertCell().textContent = o.unitValue;
row.insertCell().textContent = new Date(o.tx_time);
});
}).catch(error => { }).catch(error => {
if (error instanceof ResponseError) { if (error instanceof ResponseError) {
let response = JSON.parse(error.data) let response = JSON.parse(error.data)
@ -178,7 +289,7 @@
} else } else
console.error(error); console.error(error);
}) })
} };
const UI_evt = {}; const UI_evt = {};
@ -214,11 +325,29 @@
.catch(error => console.error(error)); .catch(error => console.error(error));
}; };
UI_evt.cancelOrders = function() {
let container = document.getElementById('my-orders');
let cancel = [];
let inputs = container.getElementsByTagName('input')
for (let i = 0; i < inputs.length; i++) {
if (inputs[i].type === "checkbox" && inputs[i].checked) {
let row = inputs[i].parentElement.parentElement
let id = row.dataset['id'];
let type = row.parentElement.dataset['type'];
cancel.push([type, id]);
}
}
cancel.forEach(o => cancelOrder(o[0], o[1])
.then(result => console.log(result))
.catch(error => console.error(o, error)))
};
(function init() { (function init() {
account(); account();
refresh(); refresh();
})(); })();
</script> </script>
</body> </body>
</html> </html>

View File

@ -41,6 +41,9 @@ module.exports = function App(secret, DB) {
app.post('/buy', Request.PlaceBuyOrder); app.post('/buy', Request.PlaceBuyOrder);
app.post('/sell', Request.PlaceSellOrder); app.post('/sell', Request.PlaceSellOrder);
//cancel sell or buy order
app.post('/cancel', Request.CancelOrder);
//list sell or buy order //list sell or buy order
app.get('/list-sellorders', Request.ListSellOrders); app.get('/list-sellorders', Request.ListSellOrders);
app.get('/list-buyorders', Request.ListBuyOrders); app.get('/list-buyorders', Request.ListBuyOrders);

View File

@ -120,6 +120,30 @@ function addBuyOrder(floID, quantity, max_price) {
}); });
} }
function cancelOrder(type, id, floID) {
return new Promise((resolve, reject) => {
if (!floID || !floCrypto.validateAddr(floID))
return reject(INVALID("Invalid FLO ID"));
let tableName;
if (type === "buy")
tableName = "BuyOrder";
else if (type === "sell")
tableName = "SellOrder";
else
return reject(INVALID("Invalid Order type! Order type must be buy (or) sell"));
DB.query(`SELECT floID FROM ${tableName} WHERE id=?`, [id]).then(result => {
if (result.length < 1)
return reject(INVALID("Order not found!"));
else if (result[0].floID !== floID)
return reject(INVALID("Order doesnt belong to the current user"));
//Delete the order
DB.query(`DELETE FROM ${tableName} WHERE id=?`, [id])
.then(result => resolve(tableName + "#" + id + " cancelled successfully"))
.catch(error => reject(error));
}).catch(error => reject(error));
});
}
function matchBuyAndSell() { function matchBuyAndSell() {
let cur_price = net_FLO_price; let cur_price = net_FLO_price;
//get the best buyer //get the best buyer
@ -306,6 +330,7 @@ let refresher = setInterval(intervalFunction, REFRESH_INTERVAL);
module.exports = { module.exports = {
addBuyOrder, addBuyOrder,
addSellOrder, addSellOrder,
cancelOrder,
getAccountDetails, getAccountDetails,
set DB(db) { set DB(db) {
DB = db; DB = db;

View File

@ -109,6 +109,20 @@ function PlaceBuyOrder(req, res) {
}); });
} }
function CancelOrder(req, res) {
let data = req.body,
session = req.session;
market.cancelOrder(data.orderType, data.orderID, session.user_id)
.then(result => res.send(result))
.catch(error => {
console.error(error);
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
else
res.status(INTERNAL.e_code).send("Order cancellation failed! Try again later!");
});
}
function ListSellOrders(req, res) { function ListSellOrders(req, res) {
//TODO: Limit size (best) //TODO: Limit size (best)
DB.query("SELECT * FROM SellOrder ORDER BY time_placed") DB.query("SELECT * FROM SellOrder ORDER BY time_placed")
@ -168,6 +182,7 @@ module.exports = {
Logout, Logout,
PlaceBuyOrder, PlaceBuyOrder,
PlaceSellOrder, PlaceSellOrder,
CancelOrder,
ListSellOrders, ListSellOrders,
ListBuyOrders, ListBuyOrders,
ListTransactions, ListTransactions,