Skip to content

Commit 8f803d4

Browse files
authored
Create sequential numbers for the entities like IR, CR, AP ...etc (#637)
* requirement source title related fix * permissions settings for enforcements
1 parent 92f4fa6 commit 8f803d4

File tree

23 files changed

+288
-74
lines changed

23 files changed

+288
-74
lines changed

compliance-api/src/compliance_api/models/administrative_penalty.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
from sqlalchemy.orm import relationship
99
from sqlalchemy.sql import and_, func, not_, or_
1010

11-
from compliance_api.models.base_model import BaseModelVersioned
11+
from compliance_api.models.base_model import BaseModelVersioned, db
1212
from compliance_api.models.case_file import CaseFile as CaseFileModel
1313
from compliance_api.models.inspection import Inspection as InspectionModel
1414
from compliance_api.models.inspection import InspectionRequirement
1515
from compliance_api.models.utils import with_session
1616
from compliance_api.utils.constant import DELETE_DIC_PARAMS
17+
from compliance_api.utils.util import get_sorted_numbers_from_generated_code
1718

1819

1920
class ReferralStatusEnum(Enum):
@@ -330,6 +331,29 @@ def get_count_by_project_nd_case_file_id(cls, project_id: int, case_file_id: int
330331
)
331332
return result.administrative_penalty_count if result else 0
332333

334+
@classmethod
335+
def get_latest_administrative_penalty_number_count(
336+
cls, case_file_id: int, project_id: int, pattern
337+
):
338+
"""Return administrative penalty numbers for the case file/project.
339+
340+
Only numbers matching the provided pattern are returned.
341+
"""
342+
rows = (
343+
db.session.query(cls.administrative_penalty_number)
344+
.join(InspectionModel, InspectionModel.id == cls.inspection_id)
345+
.join(CaseFileModel, CaseFileModel.id == InspectionModel.case_file_id)
346+
.filter(
347+
CaseFileModel.project_id == project_id,
348+
InspectionModel.case_file_id == case_file_id,
349+
cls.administrative_penalty_number.op("~")(pattern),
350+
cls.is_active.is_(True),
351+
cls.is_deleted.is_(False),
352+
)
353+
.all()
354+
)
355+
return get_sorted_numbers_from_generated_code(rows, "AP")
356+
333357
@classmethod
334358
def get_administrative_penalties_by_case_files(
335359
cls, case_file_ids: list[int], open_aps_only: bool = False

compliance-api/src/compliance_api/models/charge_recommendation.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
from sqlalchemy.orm import relationship
99
from sqlalchemy.sql import func
1010

11-
from compliance_api.models.base_model import BaseModelVersioned
11+
from compliance_api.models.base_model import BaseModelVersioned, db
1212
from compliance_api.models.case_file import CaseFile as CaseFileModel
1313
from compliance_api.models.inspection import Inspection as InspectionModel
1414
from compliance_api.models.utils import with_session
1515
from compliance_api.utils.constant import DELETE_DIC_PARAMS
16+
from compliance_api.utils.util import get_sorted_numbers_from_generated_code
1617

1718

1819
class ChargeRecommendationStatusEnum(Enum):
@@ -376,3 +377,26 @@ def get_count_by_project_nd_case_file_id(
376377
.first()
377378
)
378379
return result.charge_recommendation_count if result else 0
380+
381+
@classmethod
382+
def get_latest_charge_recommendation_number_count(
383+
cls, case_file_id: int, project_id: int, pattern
384+
):
385+
"""Return charge recommendation numbers for the case file/project.
386+
387+
Only numbers matching the provided pattern are returned.
388+
"""
389+
rows = (
390+
db.session.query(cls.charge_recommendation_number)
391+
.join(InspectionModel, InspectionModel.id == cls.inspection_id)
392+
.join(CaseFileModel, CaseFileModel.id == InspectionModel.case_file_id)
393+
.filter(
394+
CaseFileModel.project_id == project_id,
395+
InspectionModel.case_file_id == case_file_id,
396+
cls.charge_recommendation_number.op("~")(pattern),
397+
cls.is_active.is_(True),
398+
cls.is_deleted.is_(False),
399+
)
400+
.all()
401+
)
402+
return get_sorted_numbers_from_generated_code(rows, "CR")

compliance-api/src/compliance_api/models/complaint/complaint.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
from sqlalchemy.orm import relationship
1919

2020
from compliance_api.utils.constant import DELETE_DIC_PARAMS
21+
from compliance_api.utils.util import get_sorted_numbers_from_generated_code
2122

22-
from ..base_model import BaseModelVersioned
23+
from ..base_model import BaseModelVersioned, db
2324
from ..case_file import CaseFile as CaseFileModel
2425
from ..utils import with_session
2526

@@ -192,6 +193,25 @@ def get_count_by_project_nd_case_file_id(cls, project_id: int, case_file_id: int
192193
)
193194
return result.complaint_count if result else 0
194195

196+
@classmethod
197+
def get_latest_complaint_number_count(
198+
cls, case_file_id: int, project_id: int, pattern
199+
):
200+
"""Return all ir numbers based on the case file and project id where irno follows the given pattern."""
201+
rows = (
202+
db.session.query(cls.complaint_number)
203+
.join(CaseFileModel, CaseFileModel.id == cls.case_file_id)
204+
.filter(
205+
CaseFileModel.project_id == project_id,
206+
cls.case_file_id == case_file_id,
207+
cls.complaint_number.op("~")(pattern),
208+
cls.is_active.is_(True),
209+
cls.is_deleted.is_(False),
210+
)
211+
.all()
212+
)
213+
return get_sorted_numbers_from_generated_code(rows, "CM")
214+
195215
@classmethod
196216
@with_session
197217
def create_complaint(cls, complaint_obj, session=None):

compliance-api/src/compliance_api/models/inspection/inspection.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from sqlalchemy.orm import relationship
1717

1818
from compliance_api.utils.constant import DELETE_DIC_PARAMS
19+
from compliance_api.utils.util import get_sorted_numbers_from_generated_code
1920

2021
from ..base_model import BaseModelVersioned, db
2122
from ..case_file import CaseFile as CaseFileModel
@@ -172,6 +173,22 @@ def get_count_by_project_nd_case_file_id(cls, project_id: int, case_file_id: int
172173
)
173174
return result.inspection_count if result else 0
174175

176+
@classmethod
177+
def get_latest_ir_number_count(cls, case_file_id: int, project_id: int, pattern):
178+
"""Return all ir numbers based on the case file and project id where irno follows the given pattern."""
179+
rows = (
180+
db.session.query(cls.ir_number)
181+
.filter(
182+
cls.case_file_id == case_file_id,
183+
cls.project_id == project_id,
184+
cls.ir_number.op("~")(pattern),
185+
cls.is_active.is_(True),
186+
cls.is_deleted.is_(False),
187+
)
188+
.all()
189+
)
190+
return get_sorted_numbers_from_generated_code(rows, "IR")
191+
175192
@classmethod
176193
@with_session
177194
def create_inspection(cls, inspection_obj, session=None):

compliance-api/src/compliance_api/models/order.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
from sqlalchemy.orm import relationship
77

88
from compliance_api.utils.constant import DELETE_DIC_PARAMS
9+
from compliance_api.utils.util import get_sorted_numbers_from_generated_code
910

10-
from .base_model import BaseModelVersioned
11+
from .base_model import BaseModelVersioned, db
1112
from .case_file import CaseFile as CaseFileModel
1213
from .inspection import Inspection as InspectionModel
1314
from .utils import with_session
@@ -246,6 +247,24 @@ def get_count_by_project_nd_case_file_id(cls, project_id: int, case_file_id: int
246247
)
247248
return result.order_count if result else 0
248249

250+
@classmethod
251+
def get_latest_order_number_count(cls, case_file_id: int, project_id: int, pattern):
252+
"""Return all ir numbers based on the case file and project id where irno follows the given pattern."""
253+
rows = (
254+
db.session.query(cls.order_number)
255+
.join(InspectionModel, InspectionModel.id == cls.inspection_id)
256+
.join(CaseFileModel, CaseFileModel.id == InspectionModel.case_file_id)
257+
.filter(
258+
CaseFileModel.project_id == project_id,
259+
InspectionModel.case_file_id == case_file_id,
260+
cls.order_number.op("~")(pattern),
261+
cls.is_active.is_(True),
262+
cls.is_deleted.is_(False),
263+
)
264+
.all()
265+
)
266+
return get_sorted_numbers_from_generated_code(rows, "OR")
267+
249268
@classmethod
250269
def get_by_order_number(cls, order_number: str):
251270
"""Find an order by order number."""

compliance-api/src/compliance_api/models/restorative_justice.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
from sqlalchemy import ForeignKey, Index, Integer, String, Text, and_
88
from sqlalchemy.orm import relationship
99

10-
from compliance_api.models.base_model import BaseModelVersioned
10+
from compliance_api.models.base_model import BaseModelVersioned, db
11+
from compliance_api.models.case_file import CaseFile as CaseFileModel
1112
from compliance_api.models.inspection import Inspection as InspectionModel
1213
from compliance_api.models.utils import with_session
1314
from compliance_api.utils.constant import DELETE_DIC_PARAMS
15+
from compliance_api.utils.util import get_sorted_numbers_from_generated_code
1416

1517

1618
class RestorativeJusticeStatusEnum(Enum):
@@ -301,3 +303,26 @@ def get_count_by_project_nd_case_file_id(
301303
)
302304
.count()
303305
)
306+
307+
@classmethod
308+
def get_latest_restorative_justice_number_count(
309+
cls, case_file_id: int, project_id: int, pattern
310+
):
311+
"""Return restorative justice numbers for the case file/project.
312+
313+
Only numbers matching the provided pattern are returned.
314+
"""
315+
rows = (
316+
db.session.query(cls.restorative_justice_number)
317+
.join(InspectionModel, InspectionModel.id == cls.inspection_id)
318+
.join(CaseFileModel, CaseFileModel.id == InspectionModel.case_file_id)
319+
.filter(
320+
CaseFileModel.project_id == project_id,
321+
InspectionModel.case_file_id == case_file_id,
322+
cls.restorative_justice_number.op("~")(pattern),
323+
cls.is_active.is_(True),
324+
cls.is_deleted.is_(False),
325+
)
326+
.all()
327+
)
328+
return get_sorted_numbers_from_generated_code(rows, "RJ")

compliance-api/src/compliance_api/models/warning_letter.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
from sqlalchemy.orm import relationship
99
from sqlalchemy.sql import func
1010

11-
from compliance_api.models.base_model import BaseModelVersioned
11+
from compliance_api.models.base_model import BaseModelVersioned, db
1212
from compliance_api.models.case_file import CaseFile as CaseFileModel
1313
from compliance_api.models.inspection import Inspection as InspectionModel
1414
from compliance_api.models.utils import with_session
1515
from compliance_api.utils.constant import DELETE_DIC_PARAMS
16+
from compliance_api.utils.util import get_sorted_numbers_from_generated_code
1617

1718

1819
class WarningLetterStatusEnum(Enum):
@@ -246,3 +247,26 @@ def get_count_by_project_nd_case_file_id(cls, project_id: int, case_file_id: int
246247
.first()
247248
)
248249
return result.warning_letter_count if result else 0
250+
251+
@classmethod
252+
def get_latest_warning_letter_number_count(
253+
cls, case_file_id: int, project_id: int, pattern
254+
):
255+
"""Return warning letter numbers for the case file/project.
256+
257+
Only numbers matching the provided pattern are returned.
258+
"""
259+
rows = (
260+
db.session.query(cls.warning_letter_number)
261+
.join(InspectionModel, InspectionModel.id == cls.inspection_id)
262+
.join(CaseFileModel, CaseFileModel.id == InspectionModel.case_file_id)
263+
.filter(
264+
CaseFileModel.project_id == project_id,
265+
InspectionModel.case_file_id == case_file_id,
266+
cls.warning_letter_number.op("~")(pattern),
267+
cls.is_active.is_(True),
268+
cls.is_deleted.is_(False),
269+
)
270+
.all()
271+
)
272+
return get_sorted_numbers_from_generated_code(rows, "WN")

compliance-api/src/compliance_api/schemas/inspection_approval.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
"""Schema for Inspection Record Approval."""
22

3-
from compliance_api.schemas.common import KeyValueSchema
43
from marshmallow import EXCLUDE, ValidationError, fields, post_dump, post_load, validate
54
from marshmallow_enum import EnumField
65

76
from compliance_api.models.inspection_record_approval import InspectionRecordApproval as InspectionRecordApprovalModel
87
from compliance_api.models.inspection_record_approval import IRApprovalStatusEnum
9-
from compliance_api.schemas.common import KeyValueSchema
108
from compliance_api.utils.constant import INPUT_DATE_TIME_FORMAT
119

1210
from .base_schema import AutoSchemaBase, BaseSchema
1311
from .staff_user import StaffUserSchema
12+
from . import KeyValueSchema
1413

1514

1615
class InspectionRecordApprovalSchema(

compliance-api/src/compliance_api/services/administrative_penalty.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,9 @@ def _create_administrative_penalty_number(project_id: int, case_file_id: int) ->
446446
if case_file.project_id != project_id:
447447
raise UnprocessableEntityError("Given project and case file don't match")
448448

449-
count = AdministrativePenalty.get_count_by_project_nd_case_file_id(
450-
project_id, case_file_id
449+
pattern = rf"^{project_code}_{case_file.case_file_number}_AP[0-9]{{3}}$"
450+
count = AdministrativePenalty.get_latest_administrative_penalty_number_count(
451+
case_file_id, project_id, pattern
451452
)
452-
serial_number = f"{count + 1:03}"
453+
serial_number = f"{count:03}"
453454
return f"{project_code}_{case_file.case_file_number}_AP{serial_number}"

compliance-api/src/compliance_api/services/charge_recommendation.py

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
ChargeRecommendation, ChargeRecommendationInspectionRequirementMap)
99
from compliance_api.models.cr_sentence_type_mapping import CRSentenceTypeMapping
1010
from compliance_api.models.db import session_scope
11-
from compliance_api.models.inspection import Inspection as InspectionModel
1211
from compliance_api.services.service_utils import ServiceUtils
1312

1413

@@ -233,26 +232,6 @@ def _create_requirement_mappings(
233232
mapping_data, session
234233
)
235234

236-
@classmethod
237-
def _generate_charge_recommendation_number(cls, inspection_id: int) -> str:
238-
"""Generate a unique charge recommendation number."""
239-
inspection = InspectionModel.find_by_id(inspection_id)
240-
if not inspection:
241-
raise ResourceNotFoundError("Given inspection doesn't exist")
242-
243-
project_code = ServiceUtils.get_project_abbreviation(inspection.project_id)
244-
case_file = CaseFileModel.find_by_id(inspection.case_file_id)
245-
if not case_file:
246-
raise ResourceNotFoundError("Given case file doesn't exist")
247-
if case_file.project_id != inspection.project_id:
248-
raise UnprocessableEntityError("Given project and case file don't match")
249-
250-
count = ChargeRecommendation.get_count_by_project_nd_case_file_id(
251-
inspection.project_id, inspection.case_file_id
252-
)
253-
serial_number = f"{count + 1:03}"
254-
return f"{project_code}_{case_file.case_file_number}_CR{serial_number}"
255-
256235

257236
def _extract_cr_data(charge_recommendation_data):
258237
"""Extract charge recommendation data."""
@@ -300,9 +279,9 @@ def _create_charge_recommendation_number(project_id: int, case_file_id: int) ->
300279
raise ResourceNotFoundError("Given case file doesn't exist")
301280
if case_file.project_id != project_id:
302281
raise UnprocessableEntityError("Given project and case file don't match")
303-
304-
count = ChargeRecommendation.get_count_by_project_nd_case_file_id(
305-
project_id, case_file_id
282+
pattern = rf"^{project_code}_{case_file.case_file_number}_CR[0-9]{{3}}$"
283+
count = ChargeRecommendation.get_latest_charge_recommendation_number_count(
284+
case_file_id, project_id, pattern
306285
)
307-
serial_number = f"{count + 1:03}"
286+
serial_number = f"{count:03}"
308287
return f"{project_code}_{case_file.case_file_number}_CR{serial_number}"

0 commit comments

Comments
 (0)