vanitha commited on
Commit
544529e
·
1 Parent(s): 48f857d

(staff)-Added convert_objectid_to_str utility for BSON serialization

Browse files
app/staff/services/staff_service.py CHANGED
@@ -22,7 +22,7 @@ from app.staff.schemas.staff_schema import (
22
  StaffListResponse
23
  )
24
  from app.constants.staff_types import Designation, stafftatus
25
- from app.utils.response import convert_objectid_to_str
26
 
27
  logger = get_logger(__name__)
28
 
 
22
  StaffListResponse
23
  )
24
  from app.constants.staff_types import Designation, stafftatus
25
+ from app.utils.utils import convert_objectid_to_str
26
 
27
  logger = get_logger(__name__)
28
 
app/utils/response.py CHANGED
@@ -6,11 +6,7 @@ from datetime import datetime
6
  from uuid import uuid4
7
 
8
 
9
- def convert_objectid_to_str(documents: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
10
- for doc in documents:
11
- if "_id" in doc and doc["_id"] is not None:
12
- doc["_id"] = str(doc["_id"])
13
- return documents
14
 
15
 
16
  def success_response(
 
6
  from uuid import uuid4
7
 
8
 
9
+
 
 
 
 
10
 
11
 
12
  def success_response(
app/utils/utils.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from datetime import datetime
3
+ from typing import Any, Dict, List
4
+ from app.core.logging import get_logger
5
+ from sqlalchemy import text
6
+ from sqlalchemy.ext.asyncio import AsyncSession
7
+
8
+ logger = get_logger(__name__)
9
+
10
+ def convert_objectid_to_str(documents: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
11
+ for doc in documents:
12
+ if "_id" in doc and doc["_id"] is not None:
13
+ doc["_id"] = str(doc["_id"])
14
+ return documents
15
+
16
+ async def get_next_sequence(db: AsyncSession, seq_name: str) -> int:
17
+ """Get next value from PostgreSQL sequence"""
18
+ try:
19
+ result = await db.execute(text(f"SELECT nextval('{seq_name}')"))
20
+ return result.scalar()
21
+ except Exception as e:
22
+ logger.error(f"Error getting sequence {seq_name}: {e}")
23
+ raise
24
+
25
+ async def create_sequence_if_not_exists(db: AsyncSession, seq_name: str, start_value: int = 1):
26
+ """Create PostgreSQL sequence if it doesn't exist"""
27
+ try:
28
+ # Check if sequence exists
29
+ check_query = text("""
30
+ SELECT EXISTS (
31
+ SELECT 1 FROM pg_sequences
32
+ WHERE schemaname = 'public' AND sequencename = :seq_name
33
+ )
34
+ """)
35
+ result = await db.execute(check_query, {"seq_name": seq_name})
36
+ exists = result.scalar()
37
+
38
+ if not exists:
39
+ create_query = text(f"CREATE SEQUENCE {seq_name} START {start_value}")
40
+ await db.execute(create_query)
41
+ await db.commit()
42
+ logger.info(f"Created sequence {seq_name} starting at {start_value}")
43
+
44
+ except Exception as e:
45
+ logger.error(f"Error creating sequence {seq_name}: {e}")
46
+ raise
47
+
48
+
49
+ async def sync_pos_sequence(db: AsyncSession):
50
+ """Sync POS sequence with existing data to prevent duplicates"""
51
+ try:
52
+ # Find the highest sequence number for current year
53
+ current_year = datetime.now().year
54
+ result = await db.execute(text(f"""
55
+ SELECT COALESCE(MAX(
56
+ CAST(SUBSTRING(sale_code FROM 'POS-{current_year}-([0-9]+)') AS INTEGER)
57
+ ), 0) as max_seq
58
+ FROM trans.pos_sale
59
+ WHERE sale_code LIKE 'POS-{current_year}%'
60
+ """))
61
+
62
+ max_seq = result.scalar() or 0
63
+ next_seq = max_seq + 1
64
+
65
+ # Set sequence to next available number
66
+ await db.execute(text(f"SELECT setval('pos_number_seq', {next_seq}, false)"))
67
+ logger.info(f"Synced POS sequence to {next_seq} based on existing data")
68
+
69
+ except Exception as e:
70
+ logger.error(f"Error syncing POS sequence: {e}")
71
+ raise
72
+
73
+
74
+ async def initialize_sequences(db: AsyncSession):
75
+ """Initialize all required sequences for purchases module"""
76
+ sequences = [
77
+ ("POS_number_seq", 1)
78
+ ]
79
+ for seq_name, start_value in sequences:
80
+ await create_sequence_if_not_exists(db, seq_name, start_value)
81
+
82
+ def generate_sale_code(sequence_number: int, prefix: str = "POS") -> str:
83
+ """
84
+ Generate Sale order number with format: POS-YYYY-NNNNNN
85
+
86
+ Args:
87
+ sequence_number: Next sequence value
88
+ prefix: POS number prefix (default: "POS")
89
+
90
+ Returns:
91
+ Formatted POS number like "POS-2024-000001"
92
+ """
93
+ current_year = datetime.now().year
94
+ return f"{prefix}-{current_year}-{sequence_number:06d}"
95
+
96
+ async def get_next_sale_code(db: AsyncSession, prefix: str = "POS") -> str:
97
+ """Get next available POS number"""
98
+ # Ensure sequence exists before getting next value
99
+ await create_sequence_if_not_exists(db, "pos_number_seq", 1)
100
+ seq_number = await get_next_sequence(db, "pos_number_seq")
101
+ return generate_sale_code(seq_number, prefix)
102
+