Skip to content

Commit

Permalink
close trade
Browse files Browse the repository at this point in the history
  • Loading branch information
pashazzz committed Aug 6, 2024
1 parent c1807d0 commit 63f8bc7
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 4 deletions.
31 changes: 28 additions & 3 deletions backend/modules/bears/bears.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import passport from 'passport'

import IBearEntity from '../../../interfaces/IBearEntity'
import BearsModel from './bears.model'
import BidsModel from '../bids/bids.model'
import UsersMiddleware from '../users/users.middleware'
import { isDatesSame } from '../../services/dates'

Expand All @@ -19,6 +20,8 @@ router.get('/:id',
UsersMiddleware.isAuthenticated,
async (req: Request<{id: number}>, res: Response) => {
const bear: IBearEntity | undefined = await BearsModel.fetchBearById(Number(req.params.id))
// don't show to owner who did last bid
delete(bear?.lastBidUserId)
const status: number = bear === undefined ? 404 : 200

res.status(status).json(bear)
Expand All @@ -42,6 +45,8 @@ router.post('/changePrice',
if (bear.price === req.body.price) {
return res.status(200).json({notNeedToChange: true})
}
// don't show to owner who did last bid
delete(bear.lastBidUserId)
try {
await BearsModel.updateField(req.body.id, 'price', req.body.price)
} catch(e) {
Expand Down Expand Up @@ -95,16 +100,36 @@ router.post('/changePeriod',
return res.status(404).send('Bear with this id is not exists... For you?..')
}

// delete trade period
try {
await BearsModel.updateTradePeriod(req.body.id, null, null)
} catch(e) {
console.log(e)
return res.status(400).send('Bad request')
}
delete(bear.tradeStart)
delete(bear.tradeEnd)

if (bear.maxBid && bear.lastBidUserId) {
// transfer credits
try {
await BidsModel.transferCreditsForBid(bear)
} catch (e) {
console.log(e)
res.status(400).send('Cannot transfer credits')
}

// change bear owner, if it have at least one bid
try {
await BearsModel.changeOwner(bear)
} catch(e) {
console.log(e)
res.status(400).send('Cannot change owner')
}
}

// delete all former bids
BidsModel.cleanBidsForBear(bear.id)

res.status(200).json(bear)
res.status(200).json({closed: true})
}

)
Expand Down
22 changes: 21 additions & 1 deletion backend/modules/bears/bears.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// import { db } from "../../../app"
import { getAll, getOne, sqlQuery } from "../../services/db"
import IBearEntity from "../../../interfaces/IBearEntity"
import { IUserPublicFields } from "../../../interfaces/IUserEntity"

const fetchBears = async (ofUserId?: number): Promise<IBearEntity[]> => {
const sql = `SELECT bears.*, MAX(bids.value) as maxBid
Expand All @@ -12,7 +13,10 @@ const fetchBears = async (ofUserId?: number): Promise<IBearEntity[]> => {
}

const fetchBearById = (id: number): Promise<IBearEntity | undefined> => {
const sql = `SELECT bears.*, MAX(bids.value) as maxBid
const sql = `SELECT
bears.*,
MAX(bids.value) as maxBid,
bids.userId as lastBidUserId
FROM bears
LEFT JOIN bids ON bids.bearId = bears.id
WHERE bears.id = ${id}
Expand All @@ -37,10 +41,26 @@ const updateTradePeriod = (id: number, tradeStart: string | null, tradeEnd: stri
return sqlQuery(sql) as Promise<void>
}

const changeOwner = async (bear: IBearEntity) => {
const newOwner = await getOne(`SELECT id, username, email, roles
FROM users
WHERE id = ${bear.lastBidUserId}`) as IUserPublicFields

if (!newOwner) {
return Promise.reject({reason: 'user not exists'})
}

const sql = `UPDATE bears SET
ownerId = ${newOwner.id}
WHERE id = ${bear.id}`
return sqlQuery(sql) as Promise<void>
}

export default {
fetchBears,
fetchBearById,
fetchBearByUrl,
updateField,
updateTradePeriod,
changeOwner,
}
47 changes: 47 additions & 0 deletions backend/modules/bids/bids.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { getOne, sqlQuery } from "../../services/db"

import UsersModel from "../users/users.model"
import IBidEntity from "../../../interfaces/IBidEntity"
import IBearEntity from "../../../interfaces/IBearEntity"
import { IUserEntity } from "../../../interfaces/IUserEntity"

const getLastBid = (bearId: number) => {
const sql = `SELECT * FROM bids WHERE bearId = ${bearId} ORDER BY id DESC LIMIT 1`
Expand Down Expand Up @@ -27,9 +31,52 @@ const deleteBid = (id: number) => {
return sqlQuery(sql) as Promise<void>
}

const transferCreditsForBid = async (bear: IBearEntity) => {
const amount = bear.maxBid
const receiverId = bear.ownerId
const payerId = bear.lastBidUserId
if (!amount || !payerId) {
return Promise.reject(`No amount to pay (${amount}) or not exists the payer with id ${payerId}`)
}
const payer: IUserEntity|undefined = await UsersModel.findUserById(payerId)
if (!payer) {
return Promise.reject(`Payer with id ${payerId} is not exists`)
}
if (payer.wallet < amount) {
return Promise.reject(`Payer have not enough credits (${amount}) in wallet`)
}

try {
const sql = `UPDATE users SET
wallet = wallet - ${amount}
WHERE id = ${payerId}`
await sqlQuery(sql)
} catch (e) {
return Promise.reject(`Cannot transfer ${amount} credits from payer with id ${payerId}`)
}

try {
const sql = `UPDATE users SET
wallet = wallet + ${amount}
WHERE id = ${receiverId}`
await sqlQuery(sql)
} catch (e) {
return Promise.reject(`Cannot transfer ${amount} credits to receiver with id ${receiverId}`)
}

return Promise.resolve()
}

const cleanBidsForBear = (id: number) => {
const sql = `DELETE FROM bids WHERE bearId=${id}`
return sqlQuery(sql) as Promise<void>
}

export default {
getLastBid,
createBid,
fetchBidById,
deleteBid,
transferCreditsForBid,
cleanBidsForBear,
}
1 change: 1 addition & 0 deletions interfaces/IBearEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export default interface IBearEntity {
tradeEnd?: string,
createdAt: string,
maxBid?: number,
lastBidUserId?: number,
}
25 changes: 25 additions & 0 deletions src/components/BearViewOwnerPart/BearViewOwnerPart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FC, useEffect, useState } from 'react'
import { getRequestWithAuth, postRequestWithAuth } from '../../helpers/backendRequsts'
import { useAppSelector } from '../../helpers/reduxHooks'

import Button, { ButtonVariants } from '../Base/Button'
import PriceButtons from '../PriceButtons'
import TradePeriod from '../TradePeriod'
import IBearEntity from '../../../interfaces/IBearEntity'
Expand Down Expand Up @@ -64,6 +65,25 @@ const BearViewOwnerPart: FC<BearViewOwnerPartProps> = ({ bear }) => {
})
}, [bear, tradeStart, tradeEnd])

const closeCallbackAction = () => {
if (!window.confirm(`
Do you really want to close the trade?
!!!
If it has at least one bid, the bear will be moved to a new owner
!!!`)) {
return
}
postRequestWithAuth(`/bears/closeTrade`, {
id: bear.id,
})
.then(res => {
console.log(res)
window.location.reload()
})
.catch(err => console.log(err))
}

return (
<div className="bear-container-owner-part">
<div className="bear-container-img">
Expand All @@ -83,6 +103,11 @@ const BearViewOwnerPart: FC<BearViewOwnerPartProps> = ({ bear }) => {
tradeEnd={tradeEnd}
setTradeEnd={setTradeEnd}
/>
<Button
text='Close trade'
variant={ButtonVariants.danger}
onClick={closeCallbackAction}
/>
</div>
</div>
)
Expand Down

0 comments on commit 63f8bc7

Please sign in to comment.