Aryan Jain commited on
Commit
1eb956a
·
1 Parent(s): 1f780d7

update letters and evaluation apis

Browse files
src/controllers/__init__.py CHANGED
@@ -23,12 +23,10 @@ api_router.include_router(
23
  tags=["Proposal Detailed Analysis"],
24
  )
25
  api_router.include_router(
26
- LetterController().router, prefix="/letters", tags=["Letters"]
27
  )
28
  api_router.include_router(
29
- EvaluationController().router,
30
- prefix="/evaluation_criteria",
31
- tags=["Evaluation Criteria"],
32
  )
33
 
34
  __all__ = ["api_router"]
 
23
  tags=["Proposal Detailed Analysis"],
24
  )
25
  api_router.include_router(
26
+ LetterController().router
27
  )
28
  api_router.include_router(
29
+ EvaluationController().router
 
 
30
  )
31
 
32
  __all__ = ["api_router"]
src/controllers/_evaluation_controller.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import APIRouter, HTTPException, Query
2
  from pydantic import BaseModel
3
  from typing import List, Optional
4
  from uuid import UUID
@@ -30,7 +30,6 @@ class EvaluationRequest(BaseModel):
30
 
31
 
32
  class UpdateEvaluationRequest(BaseModel):
33
- id: UUID
34
  rfp_id: Optional[UUID] = None
35
  evaluation_criteria: Optional[str] = None
36
  evaluation_criteria_type: Optional[EvaluationCriteriaType] = None
@@ -49,39 +48,110 @@ class EvaluationController:
49
  self.get_criteria,
50
  methods=["GET"],
51
  response_model=EvaluationResponse,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  )
53
  self.router.add_api_route(
54
  "/evaluation_criteria",
55
  self.create_criteria,
56
  methods=["POST"],
57
  response_model=EvaluationResponse,
 
58
  )
59
  self.router.add_api_route(
60
- "/evaluation_criteria",
61
  self.update_criteria,
62
  methods=["PUT"],
63
  response_model=EvaluationResponse,
 
64
  )
65
  self.router.add_api_route(
66
- "/evaluation_criteria",
67
  self.delete_criteria,
68
  methods=["DELETE"],
69
  response_model=DeleteResponse,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  )
71
 
72
  async def get_criteria(
73
- self,
74
- id: Optional[str] = Query(None),
75
- rfp_id: Optional[str] = Query(None),
76
- evaluation_criteria_type: Optional[EvaluationCriteriaType] = Query(None),
77
  ):
78
  try:
79
  async with self.evaluation_service() as service:
80
- result = await service.get_criteria(
81
- id=id,
82
- rfp_id=rfp_id,
83
- evaluation_criteria_type=evaluation_criteria_type,
84
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  return EvaluationResponse(
86
  status="success", data=[EvaluationCriteria(**r) for r in result]
87
  )
@@ -106,11 +176,11 @@ class EvaluationController:
106
  status_code=500, detail="Error creating evaluation criteria"
107
  )
108
 
109
- async def update_criteria(self, criteria: UpdateEvaluationRequest):
110
  try:
111
  async with self.evaluation_service() as service:
112
  result = await service.update_criteria(
113
- criteria.model_dump(exclude_unset=True, mode="json")
114
  )
115
  return EvaluationResponse(
116
  status="success", data=[EvaluationCriteria(**r) for r in result]
@@ -122,13 +192,33 @@ class EvaluationController:
122
  )
123
 
124
  async def delete_criteria(
125
- self, id: Optional[str] = Query(None), rfp_id: Optional[str] = Query(None)
126
  ):
127
  try:
128
- if not id and not rfp_id:
129
- return DeleteResponse(status="Failed to delete evaluation criteria")
130
  async with self.evaluation_service() as service:
131
- await service.delete_criteria(id=id, rfp_id=rfp_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  return DeleteResponse(status="success")
133
  except Exception as e:
134
  logger.error(e)
 
1
+ from fastapi import APIRouter, HTTPException, Query, Path
2
  from pydantic import BaseModel
3
  from typing import List, Optional
4
  from uuid import UUID
 
30
 
31
 
32
  class UpdateEvaluationRequest(BaseModel):
 
33
  rfp_id: Optional[UUID] = None
34
  evaluation_criteria: Optional[str] = None
35
  evaluation_criteria_type: Optional[EvaluationCriteriaType] = None
 
48
  self.get_criteria,
49
  methods=["GET"],
50
  response_model=EvaluationResponse,
51
+ tags=["Evaluation Criteria"],
52
+ )
53
+ self.router.add_api_route(
54
+ "/evaluation_criteria/{id}",
55
+ self.get_criteria_by_id,
56
+ methods=["GET"],
57
+ response_model=EvaluationResponse,
58
+ tags=["Evaluation Criteria by ID"],
59
+ )
60
+ self.router.add_api_route(
61
+ "/rpfs/{rfp_id}/evaluation_criteria",
62
+ self.get_criteria_by_rfp_id,
63
+ methods=["GET"],
64
+ response_model=EvaluationResponse,
65
+ tags=["Evaluation Criteria by RFP ID"],
66
+ )
67
+ self.router.add_api_route(
68
+ "/rpfs/{rfp_id}/evaluation_criteria/{id}",
69
+ self.get_criteria_by_proposal_and_rfp_id,
70
+ methods=["GET"],
71
+ response_model=EvaluationResponse,
72
+ tags=["Evaluation Criteria by Proposal and RFP ID"],
73
  )
74
  self.router.add_api_route(
75
  "/evaluation_criteria",
76
  self.create_criteria,
77
  methods=["POST"],
78
  response_model=EvaluationResponse,
79
+ tags=["Evaluation Criteria"],
80
  )
81
  self.router.add_api_route(
82
+ "/evaluation_criteria/{id}",
83
  self.update_criteria,
84
  methods=["PUT"],
85
  response_model=EvaluationResponse,
86
+ tags=["Evaluation Criteria by ID"],
87
  )
88
  self.router.add_api_route(
89
+ "/evaluation_criteria/{id}",
90
  self.delete_criteria,
91
  methods=["DELETE"],
92
  response_model=DeleteResponse,
93
+ tags=["Evaluation Criteria by ID"],
94
+ )
95
+ self.router.add_api_route(
96
+ "/rpfs/{rfp_id}/evaluation_criteria",
97
+ self.delete_criteria_by_rfp_id,
98
+ methods=["DELETE"],
99
+ response_model=DeleteResponse,
100
+ tags=["Evaluation Criteria by RFP ID"],
101
+ )
102
+ self.router.add_api_route(
103
+ "/rpfs/{rfp_id}/evaluation_criteria/{id}",
104
+ self.delete_criteria_by_proposal_and_rfp_id,
105
+ methods=["DELETE"],
106
+ response_model=DeleteResponse,
107
+ tags=["Evaluation Criteria by Proposal and RFP ID"],
108
  )
109
 
110
  async def get_criteria(
111
+ self
 
 
 
112
  ):
113
  try:
114
  async with self.evaluation_service() as service:
115
+ result = await service.get_criteria()
116
+ return EvaluationResponse(
117
+ status="success", data=[EvaluationCriteria(**r) for r in result]
118
+ )
119
+ except Exception as e:
120
+ logger.error(e)
121
+ raise HTTPException(
122
+ status_code=500, detail="Error fetching evaluation criteria"
123
+ )
124
+
125
+ async def get_criteria_by_id(self, id: str = Path(...)):
126
+ try:
127
+ async with self.evaluation_service() as service:
128
+ result = await service.get_criteria(id=id)
129
+ return EvaluationResponse(
130
+ status="success", data=[EvaluationCriteria(**r) for r in result]
131
+ )
132
+ except Exception as e:
133
+ logger.error(e)
134
+ raise HTTPException(
135
+ status_code=500, detail="Error fetching evaluation criteria"
136
+ )
137
+
138
+ async def get_criteria_by_rfp_id(self, rfp_id: str = Path(...)):
139
+ try:
140
+ async with self.evaluation_service() as service:
141
+ result = await service.get_criteria(rfp_id=rfp_id)
142
+ return EvaluationResponse(
143
+ status="success", data=[EvaluationCriteria(**r) for r in result]
144
+ )
145
+ except Exception as e:
146
+ logger.error(e)
147
+ raise HTTPException(
148
+ status_code=500, detail="Error fetching evaluation criteria"
149
+ )
150
+
151
+ async def get_criteria_by_proposal_and_rfp_id(self, rfp_id: str = Path(...), id: str = Path(...)):
152
+ try:
153
+ async with self.evaluation_service() as service:
154
+ result = await service.get_criteria(rfp_id=rfp_id, id=id)
155
  return EvaluationResponse(
156
  status="success", data=[EvaluationCriteria(**r) for r in result]
157
  )
 
176
  status_code=500, detail="Error creating evaluation criteria"
177
  )
178
 
179
+ async def update_criteria(self, criteria: UpdateEvaluationRequest, id: str = Path(...)):
180
  try:
181
  async with self.evaluation_service() as service:
182
  result = await service.update_criteria(
183
+ id=id, evaluation_criteria=criteria.model_dump(exclude_unset=True, mode="json")
184
  )
185
  return EvaluationResponse(
186
  status="success", data=[EvaluationCriteria(**r) for r in result]
 
192
  )
193
 
194
  async def delete_criteria(
195
+ self, id: str = Path(...)
196
  ):
197
  try:
 
 
198
  async with self.evaluation_service() as service:
199
+ await service.delete_criteria(id=id)
200
+ return DeleteResponse(status="success")
201
+ except Exception as e:
202
+ logger.error(e)
203
+ raise HTTPException(
204
+ status_code=500, detail="Error deleting evaluation criteria"
205
+ )
206
+
207
+ async def delete_criteria_by_rfp_id(self, rfp_id: str = Path(...)):
208
+ try:
209
+ async with self.evaluation_service() as service:
210
+ await service.delete_criteria(rfp_id=rfp_id)
211
+ return DeleteResponse(status="success")
212
+ except Exception as e:
213
+ logger.error(e)
214
+ raise HTTPException(
215
+ status_code=500, detail="Error deleting evaluation criteria"
216
+ )
217
+
218
+ async def delete_criteria_by_proposal_and_rfp_id(self, rfp_id: str = Path(...), id: str = Path(...)):
219
+ try:
220
+ async with self.evaluation_service() as service:
221
+ await service.delete_criteria(rfp_id=rfp_id, id=id)
222
  return DeleteResponse(status="success")
223
  except Exception as e:
224
  logger.error(e)
src/controllers/_letter_controller.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import APIRouter, HTTPException, Query
2
  from pydantic import BaseModel
3
  from typing import List, Optional
4
  from uuid import UUID
@@ -30,7 +30,6 @@ class LetterRequest(BaseModel):
30
 
31
 
32
  class UpdateLetterRequest(BaseModel):
33
- id: UUID
34
  proposal_id: Optional[UUID] = None
35
  letter: Optional[str] = None
36
  letter_type: Optional[LetterType] = None
@@ -45,36 +44,94 @@ class LetterController:
45
  self.letter_service = LetterService
46
  self.router = APIRouter()
47
  self.router.add_api_route(
48
- "/letter", self.get_letters, methods=["GET"], response_model=Response
 
 
 
 
 
 
 
49
  )
50
  self.router.add_api_route(
51
- "/letter", self.create_letter, methods=["POST"], response_model=Response
 
 
 
 
52
  )
53
  self.router.add_api_route(
54
- "/letter", self.update_letter, methods=["PUT"], response_model=Response
 
 
 
 
55
  )
56
  self.router.add_api_route(
57
- "/letter",
 
 
 
 
 
 
58
  self.delete_letter,
59
  methods=["DELETE"],
60
  response_model=DeleteResponse,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  )
62
 
63
  async def get_letters(
64
- self,
65
- id: Optional[str] = Query(None),
66
- proposal_id: Optional[str] = Query(None),
67
- letter_type: Optional[LetterType] = Query(None),
68
  ):
69
  try:
70
  async with self.letter_service() as service:
71
- result = await service.get_letters(
72
- id=id, proposal_id=proposal_id, letter_type=letter_type
73
- )
74
  return Response(status="success", data=[Letter(**r) for r in result])
75
  except Exception as e:
76
  logger.error(e)
77
  raise HTTPException(status_code=500, detail="Error fetching letters")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  async def create_letter(self, letter: LetterRequest):
80
  try:
@@ -87,11 +144,11 @@ class LetterController:
87
  logger.error(e)
88
  raise HTTPException(status_code=500, detail="Error creating letter")
89
 
90
- async def update_letter(self, letter: UpdateLetterRequest):
91
  try:
92
  async with self.letter_service() as service:
93
  result = await service.update_letter(
94
- letter.model_dump(exclude_unset=True, mode="json")
95
  )
96
  return Response(status="success", data=[Letter(**r) for r in result])
97
  except Exception as e:
@@ -99,13 +156,29 @@ class LetterController:
99
  raise HTTPException(status_code=500, detail="Error updating letter")
100
 
101
  async def delete_letter(
102
- self, id: Optional[str] = Query(None), proposal_id: Optional[str] = Query(None)
103
  ):
104
  try:
105
- if not id and not proposal_id:
106
- return DeleteResponse(status="Failed to delete letter")
107
  async with self.letter_service() as service:
108
- result = await service.delete_letter(id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  return DeleteResponse(status="success")
110
  except Exception as e:
111
  logger.error(e)
 
1
+ from fastapi import APIRouter, HTTPException, Query, Path
2
  from pydantic import BaseModel
3
  from typing import List, Optional
4
  from uuid import UUID
 
30
 
31
 
32
  class UpdateLetterRequest(BaseModel):
 
33
  proposal_id: Optional[UUID] = None
34
  letter: Optional[str] = None
35
  letter_type: Optional[LetterType] = None
 
44
  self.letter_service = LetterService
45
  self.router = APIRouter()
46
  self.router.add_api_route(
47
+ "/letters", self.get_letters, methods=["GET"], response_model=Response, tags=["Letters"]
48
+ )
49
+ self.router.add_api_route(
50
+ "/letters/{id}",
51
+ self.get_letters_by_id,
52
+ methods=["GET"],
53
+ response_model=Response,
54
+ tags=["Letters by ID"],
55
  )
56
  self.router.add_api_route(
57
+ "proposals/{proposal_id}/letters",
58
+ self.get_letters_by_proposal_id,
59
+ methods=["GET"],
60
+ response_model=Response,
61
+ tags=["Letters by Proposal ID"],
62
  )
63
  self.router.add_api_route(
64
+ "proposals/{proposal_id}/letters/{id}",
65
+ self.get_letters_by_proposal_and_id,
66
+ methods=["GET"],
67
+ response_model=Response,
68
+ tags=["Letters by Proposal and ID"],
69
  )
70
  self.router.add_api_route(
71
+ "/letters", self.create_letter, methods=["POST"], response_model=Response, tags=["Letters"]
72
+ )
73
+ self.router.add_api_route(
74
+ "/letters/{id}", self.update_letter, methods=["PUT"], response_model=Response, tags=["Letters by ID"]
75
+ )
76
+ self.router.add_api_route(
77
+ "/letters/{id}",
78
  self.delete_letter,
79
  methods=["DELETE"],
80
  response_model=DeleteResponse,
81
+ tags=["Letters by ID"],
82
+ )
83
+ self.router.add_api_route(
84
+ "/proposals/{proposal_id}/letters",
85
+ self.delete_letters_by_proposal_id,
86
+ methods=["DELETE"],
87
+ response_model=DeleteResponse,
88
+ tags=["Letters by Proposal ID"],
89
+ )
90
+ self.router.add_api_route(
91
+ "/proposals/{proposal_id}/letters/{id}",
92
+ self.delete_letters_by_proposal_and_id,
93
+ methods=["DELETE"],
94
+ response_model=DeleteResponse,
95
+ tags=["Letters by Proposal and ID"],
96
  )
97
 
98
  async def get_letters(
99
+ self
 
 
 
100
  ):
101
  try:
102
  async with self.letter_service() as service:
103
+ result = await service.get_letters()
 
 
104
  return Response(status="success", data=[Letter(**r) for r in result])
105
  except Exception as e:
106
  logger.error(e)
107
  raise HTTPException(status_code=500, detail="Error fetching letters")
108
+
109
+ async def get_letters_by_id(self, id: str = Path(...)):
110
+ try:
111
+ async with self.letter_service() as service:
112
+ result = await service.get_letters(id=id)
113
+ return Response(status="success", data=[Letter(**r) for r in result])
114
+ except Exception as e:
115
+ logger.error(e)
116
+ raise HTTPException(status_code=500, detail="Error fetching letter")
117
+
118
+ async def get_letters_by_proposal_id(self, proposal_id: str = Path(...)):
119
+ try:
120
+ async with self.letter_service() as service:
121
+ result = await service.get_letters(proposal_id=proposal_id)
122
+ return Response(status="success", data=[Letter(**r) for r in result])
123
+ except Exception as e:
124
+ logger.error(e)
125
+ raise HTTPException(status_code=500, detail="Error fetching letter")
126
+
127
+ async def get_letters_by_proposal_and_id(self, proposal_id: str = Path(...), id: str = Path(...)):
128
+ try:
129
+ async with self.letter_service() as service:
130
+ result = await service.get_letters(proposal_id=proposal_id, id=id)
131
+ return Response(status="success", data=[Letter(**r) for r in result])
132
+ except Exception as e:
133
+ logger.error(e)
134
+ raise HTTPException(status_code=500, detail="Error fetching letter")
135
 
136
  async def create_letter(self, letter: LetterRequest):
137
  try:
 
144
  logger.error(e)
145
  raise HTTPException(status_code=500, detail="Error creating letter")
146
 
147
+ async def update_letter(self, letter: UpdateLetterRequest, id: str = Path(...)):
148
  try:
149
  async with self.letter_service() as service:
150
  result = await service.update_letter(
151
+ id=id, letter=letter.model_dump(exclude_unset=True, mode="json")
152
  )
153
  return Response(status="success", data=[Letter(**r) for r in result])
154
  except Exception as e:
 
156
  raise HTTPException(status_code=500, detail="Error updating letter")
157
 
158
  async def delete_letter(
159
+ self, id: str = Path(...)
160
  ):
161
  try:
 
 
162
  async with self.letter_service() as service:
163
+ result = await service.delete_letter(id=id)
164
+ return DeleteResponse(status="success")
165
+ except Exception as e:
166
+ logger.error(e)
167
+ raise HTTPException(status_code=500, detail="Error deleting letter")
168
+
169
+ async def delete_letters_by_proposal_id(self, proposal_id: str = Path(...)):
170
+ try:
171
+ async with self.letter_service() as service:
172
+ result = await service.delete_letter(proposal_id=proposal_id)
173
+ return DeleteResponse(status="success")
174
+ except Exception as e:
175
+ logger.error(e)
176
+ raise HTTPException(status_code=500, detail="Error deleting letter")
177
+
178
+ async def delete_letters_by_proposal_and_id(self, proposal_id: str = Path(...), id: str = Path(...)):
179
+ try:
180
+ async with self.letter_service() as service:
181
+ result = await service.delete_letter(proposal_id=proposal_id, id=id)
182
  return DeleteResponse(status="success")
183
  except Exception as e:
184
  logger.error(e)
src/repositories/_evaluation_repository.py CHANGED
@@ -60,9 +60,8 @@ class EvaluationRepository(BaseRepository):
60
  {k: v for k, v in instance.__dict__.items() if not k.startswith("_")}
61
  ]
62
 
63
- async def update_criteria(self, evaluation_criteria: dict):
64
  async with self.get_session() as session:
65
- id = evaluation_criteria["id"]
66
  query = select(EvaluationCriteria).where(EvaluationCriteria.id == id)
67
  output = await session.execute(query)
68
  instance = output.scalars().one()
 
60
  {k: v for k, v in instance.__dict__.items() if not k.startswith("_")}
61
  ]
62
 
63
+ async def update_criteria(self, id: str, evaluation_criteria: dict):
64
  async with self.get_session() as session:
 
65
  query = select(EvaluationCriteria).where(EvaluationCriteria.id == id)
66
  output = await session.execute(query)
67
  instance = output.scalars().one()
src/repositories/_letter_repository.py CHANGED
@@ -55,9 +55,8 @@ class LetterRepository(BaseRepository):
55
  {k: v for k, v in instance.__dict__.items() if not k.startswith("_")}
56
  ]
57
 
58
- async def update_letter(self, letter: dict):
59
  async with self.get_session() as session:
60
- id = letter["id"]
61
  query = select(Letter).where(Letter.id == id)
62
  output = await session.execute(query)
63
  instance = output.scalars().one()
 
55
  {k: v for k, v in instance.__dict__.items() if not k.startswith("_")}
56
  ]
57
 
58
+ async def update_letter(self, id: str, letter: dict):
59
  async with self.get_session() as session:
 
60
  query = select(Letter).where(Letter.id == id)
61
  output = await session.execute(query)
62
  instance = output.scalars().one()
src/services/_evaluation_service.py CHANGED
@@ -27,9 +27,9 @@ class EvaluationService:
27
  async with self._evaluation_repository() as repository:
28
  return await repository.create_criteria(evaluation_criteria)
29
 
30
- async def update_criteria(self, evaluation_criteria: dict):
31
  async with self._evaluation_repository() as repository:
32
- return await repository.update_criteria(evaluation_criteria)
33
 
34
  async def delete_criteria(self, id: str = None, rfp_id: str = None):
35
  async with self._evaluation_repository() as repository:
 
27
  async with self._evaluation_repository() as repository:
28
  return await repository.create_criteria(evaluation_criteria)
29
 
30
+ async def update_criteria(self, id: str, evaluation_criteria: dict):
31
  async with self._evaluation_repository() as repository:
32
+ return await repository.update_criteria(id=id, evaluation_criteria=evaluation_criteria)
33
 
34
  async def delete_criteria(self, id: str = None, rfp_id: str = None):
35
  async with self._evaluation_repository() as repository:
src/services/_letter_service.py CHANGED
@@ -24,9 +24,9 @@ class LetterService:
24
  async with self.letter_repository() as repository:
25
  return await repository.create_letter(letter)
26
 
27
- async def update_letter(self, letter: dict):
28
  async with self.letter_repository() as repository:
29
- return await repository.update_letter(letter)
30
 
31
  async def delete_letter(self, id: str = None, proposal_id: str = None):
32
  async with self.letter_repository() as repository:
 
24
  async with self.letter_repository() as repository:
25
  return await repository.create_letter(letter)
26
 
27
+ async def update_letter(self, id: str, letter: dict):
28
  async with self.letter_repository() as repository:
29
+ return await repository.update_letter(id=id, letter=letter)
30
 
31
  async def delete_letter(self, id: str = None, proposal_id: str = None):
32
  async with self.letter_repository() as repository: