1
1
# coding=utf-8
2
+ from dataclasses import asdict
3
+
4
+ from connexion import NoContent
5
+
2
6
from src .constants import DEFAULT_LIMIT , DEFAULT_OFFSET
7
+ from src .entity .product import Product
8
+ from src .exceptions import ProductNotFoundError , UserInputError
9
+ from src .interface_adapter .http_api .decorator .with_context import with_context
10
+ from src .interface_adapter .http_api .util .error import bad_request
3
11
from src .interface_adapter .sql .decorator .auth import auth_regular_admin
4
12
from src .interface_adapter .sql .decorator .sql_session import require_sql
5
-
6
- from src .entity . product import Product
7
- from src .use_case . product_manager import ProductManager
13
+ from src . use_case . product_manager import PartialMutationRequest , ProductManager , FullMutationRequest
14
+ from src .util . context import log_extra
15
+ from src .util . log import LOG
8
16
9
17
10
18
class ProductHandler :
11
19
def __init__ (self , product_manager : ProductManager ):
12
20
self .product_manager = product_manager
13
21
22
+ @with_context
14
23
@require_sql
15
24
@auth_regular_admin
16
- def search (self , limit = DEFAULT_LIMIT , offset = DEFAULT_OFFSET , terms = None ):
17
- # TODO: LOG.debug
25
+ def search (self , ctx , limit = DEFAULT_LIMIT , offset = DEFAULT_OFFSET , terms = None ):
26
+
27
+ LOG .debug ("http_product_search_called" , extra = log_extra (ctx ,
28
+ limit = limit ,
29
+ offset = offset ,
30
+ terms = terms ))
18
31
try :
19
- result , count = self .product_manager .get_by_name (ctx , limit , offset , name , terms )
20
- except Exception :
21
- pass
22
- # TODO: except NameInputError
32
+ result , count = self .product_manager .search (ctx , product_id = None , terms = terms )
33
+ headers = {
34
+ "X-Total-Count" : count ,
35
+ 'access-control-expose-headers' : 'X-Total-Count'
36
+ }
37
+ return list (map (_map_product_to_http_response , result )), 200 , headers
23
38
24
- headers = {
25
- "X-Total-Count" : count ,
26
- "access-control-expose-headers" : "X-Total-Count"
27
- }
28
- return list (map (_map_product_to_http_response , result )), 200 , headers
39
+ except UserInputError as e :
40
+ return bad_request (e ), 400 # 400 Bad Request
29
41
42
+ @with_context
30
43
@require_sql
31
44
@auth_regular_admin
32
- def post (self , body ):
33
- pass
45
+ def post (self , ctx , body ):
46
+ """ Add a product record in the database """
47
+ LOG .debug ("http_product_post_called" , extra = log_extra (ctx , request = body ))
34
48
49
+ try :
50
+ created = self .product_manager .update_or_create (ctx , req = FullMutationRequest (
51
+ name = body .get ('name' ),
52
+ buying_price = body .get ('buying_price' ),
53
+ selling_price = body .get ('selling_price' )),
54
+ product_id = body .get ('product_id' ))
55
+ if created :
56
+ return NoContent , 201 # 201 Created
57
+ else :
58
+ return NoContent , 204 # 204 No Content
59
+
60
+ except UserInputError as e :
61
+ return bad_request (e ), 400 # 400 Bad Request
62
+
63
+ @with_context
35
64
@require_sql
36
65
@auth_regular_admin
37
- def get (self , product_id ):
38
- pass
66
+ def get (self , ctx , product_id ):
67
+ """ Get a specific account. """
68
+ LOG .debug ("http_product_get_called" , extra = log_extra (ctx , product_id = product_id ))
69
+ try :
70
+ result = self .product_manager .get_by_id (ctx , product_id )
71
+ return _map_product_to_http_response (result ), 200 # 200 OK
72
+ except ProductNotFoundError :
73
+ return NoContent , 404 # 404 Not Found
39
74
75
+ @with_context
40
76
@require_sql
41
77
@auth_regular_admin
42
- def patch (self , product_id , body ):
43
- pass
78
+ def delete (self , ctx , name ):
79
+ """ Delete the specified Product from the database """
80
+ LOG .debug ("http_product_delete_called" , extra = log_extra (ctx , name = name ))
81
+ try :
82
+ self .product_manager .delete (ctx , name )
83
+ return NoContent , 204 # 204 No Content
44
84
85
+ except ProductNotFoundError :
86
+ return NoContent , 404 # 404 Not Found
45
87
46
- def _map_account_to_http_response (product : Product ) -> dict :
88
+ @with_context
89
+ @require_sql
90
+ @auth_regular_admin
91
+ def patch (self , ctx , product_id , body ):
92
+ """ Partially update a product from the database """
93
+ LOG .debug ("http_product_patch_called" , extra = log_extra (ctx , product_id = product_id , request = body ))
94
+ try :
95
+ mutation_request = _map_http_request_to_full_mutation_request (body )
96
+ self .product_manager .update_or_create (ctx , mutation_request , product_id )
97
+ return NoContent , 204 # 204 No Content
98
+
99
+ except ProductNotFoundError :
100
+ return NoContent , 404 # 404 Not Found
101
+
102
+
103
+ def _map_http_request_to_partial_mutation_request (body ) -> PartialMutationRequest :
104
+ return PartialMutationRequest (
105
+ name = body .get ('name' ),
106
+ selling_price = body .get ('selling_price' ),
107
+ buying_price = body .get ('buying_price' ),
108
+ )
109
+
110
+
111
+ def _map_product_to_http_response (product : Product ) -> dict :
47
112
fields = {
48
113
'name' : product .name ,
49
114
'buying_price' : product .buying_price ,
50
115
'selling_price' : product .selling_price ,
116
+ 'id' : product .product_id ,
51
117
}
52
- return {k : v for k , v in fields .items () if v is not None }
118
+ return {k : v for k , v in fields .items () if v is not None }
119
+
120
+
121
+ def _map_http_request_to_full_mutation_request (body ) -> FullMutationRequest :
122
+ partial = _map_http_request_to_partial_mutation_request (body )
123
+ return FullMutationRequest (** asdict (partial ))
124
+
125
+
0 commit comments