1
1
import type { ProductRepository } from '@repositories' ;
2
2
import type { ProductQuery } from '@types' ;
3
- import { ProductNotFoundError } from '@errors' ;
3
+ import { AuctionEndedError , ProductNotFoundError } from '@errors' ;
4
4
import type { Request } from 'express' ;
5
- import { getUserIdFromRequest } from '@helpers' ;
5
+ import { getUserIdFromRequest , toUtc } from '@helpers' ;
6
6
import type {
7
7
AddProductToFavorites ,
8
+ AuctionPermissionsResponse ,
8
9
BuyProduct ,
9
10
DeleteProductFromFavorites ,
10
11
} from '@vse-bude/shared' ;
12
+ import type { Bid } from '@prisma/client' ;
11
13
import { ProductStatus } from '@prisma/client' ;
12
14
import type { VerifyService } from '@services' ;
15
+ import type { BidRepository } from '@repositories' ;
16
+ import { productMapper } from '@mappers' ;
17
+ import { auctionPermissionsMapper } from '../mapper/auction-permissions' ;
13
18
14
19
export class ProductService {
15
20
private _productRepository : ProductRepository ;
16
21
22
+ private _bidRepository : BidRepository ;
23
+
17
24
private _verifyService : VerifyService ;
18
25
19
26
constructor (
20
- categoryRepository : ProductRepository ,
27
+ productRepository : ProductRepository ,
21
28
verifyService : VerifyService ,
29
+ bidRepository : BidRepository ,
22
30
) {
23
- this . _productRepository = categoryRepository ;
31
+ this . _productRepository = productRepository ;
24
32
this . _verifyService = verifyService ;
33
+ this . _bidRepository = bidRepository ;
25
34
}
26
35
27
36
public getAll ( query : ProductQuery ) {
28
37
return this . _productRepository . getAll ( query ) ;
29
38
}
30
39
31
- public async getById ( req : Request ) {
32
- const { id } = req . params ;
33
- const product = await this . _productRepository . getById ( id ) ;
40
+ public async getById ( productId : string ) {
41
+ const product = await this . _productRepository . getById ( productId ) ;
34
42
if ( ! product ) {
35
43
throw new ProductNotFoundError ( ) ;
36
44
}
37
-
38
- product . category . title = req . t ( `categories.${ product . category . title } ` ) ;
45
+ // TODO: fix translation after localization refactor
46
+ // product.category.title = req.t(`categories.${product.category.title}`);
39
47
40
48
const currentPrice = await this . _productRepository . getCurrentPrice (
41
49
product . id ,
42
50
) ;
43
51
44
- return {
45
- ...product ,
46
- currentPrice : currentPrice ,
47
- } ;
52
+ return productMapper ( product , + currentPrice ) ;
48
53
}
49
54
50
55
public async incrementViews ( id : string , req : Request ) {
@@ -71,6 +76,42 @@ export class ProductService {
71
76
return this . _productRepository . getFavorite ( userId ) ;
72
77
}
73
78
79
+ public async getAuctionPermissions (
80
+ userId : string ,
81
+ productId : string ,
82
+ ) : Promise < AuctionPermissionsResponse > {
83
+ const product = await this . _productRepository . getById ( productId ) ;
84
+ if ( ! product ) {
85
+ throw new ProductNotFoundError ( ) ;
86
+ }
87
+
88
+ if ( toUtc ( product . endDate ) < toUtc ( ) ) {
89
+ throw new AuctionEndedError ( ) ;
90
+ }
91
+
92
+ const bids : Bid [ ] = await this . _bidRepository . getByUserAndProduct (
93
+ userId ,
94
+ productId ,
95
+ ) ;
96
+
97
+ return auctionPermissionsMapper ( ! ! bids . length ) ;
98
+ }
99
+
100
+ public async leaveAuction ( userId : string , productId : string ) {
101
+ const product = await this . _productRepository . getById ( productId ) ;
102
+ if ( ! product ) {
103
+ throw new ProductNotFoundError ( ) ;
104
+ }
105
+
106
+ if ( toUtc ( product . endDate ) < toUtc ( ) ) {
107
+ throw new AuctionEndedError ( ) ;
108
+ }
109
+
110
+ await this . _bidRepository . deleteAllByProductAndUser ( userId , productId ) ;
111
+
112
+ return this . getById ( productId ) ;
113
+ }
114
+
74
115
public async addToFavorites ( { userId, productId } : AddProductToFavorites ) {
75
116
const isInFavorite = await this . _productRepository . isInFavorite (
76
117
userId ,
0 commit comments