Fred808 commited on
Commit
0e091e4
·
verified ·
1 Parent(s): 491f5da

Upload 94 files

Browse files
app/__pycache__/main.cpython-312.pyc CHANGED
Binary files a/app/__pycache__/main.cpython-312.pyc and b/app/__pycache__/main.cpython-312.pyc differ
 
app/api/__pycache__/analytics.cpython-312.pyc CHANGED
Binary files a/app/api/__pycache__/analytics.cpython-312.pyc and b/app/api/__pycache__/analytics.cpython-312.pyc differ
 
app/api/analytics.py CHANGED
@@ -11,20 +11,24 @@ router = APIRouter()
11
 
12
  @router.get("/sales")
13
  async def get_sales_analytics(
14
- start_date: datetime = Query(default=None),
15
- end_date: datetime = Query(default=None),
16
  branch_id: Optional[int] = Query(None, description="Filter analytics by branch"),
17
  current_user: User = Depends(get_current_active_user),
18
  db: AsyncSession = Depends(get_db)
19
  ) -> Dict[str, Any]:
20
- if not start_date:
21
- start_date = datetime.now() - timedelta(days=30)
22
- if not end_date:
23
- end_date = datetime.now()
 
 
 
 
24
 
25
  # Build query conditions
26
  conditions = [
27
- Order.created_at.between(start_date, end_date),
28
  Order.status.in_(['completed', 'delivered'])
29
  ]
30
 
@@ -37,7 +41,6 @@ async def get_sales_analytics(
37
  )
38
  conditions.append(Order.branch_id == branch_id)
39
  elif not current_user.is_superuser:
40
- # Non-superusers can only see their branch's analytics
41
  conditions.append(Order.branch_id == current_user.branch_id)
42
 
43
  # Daily sales query
@@ -57,18 +60,22 @@ async def get_sales_analytics(
57
  daily_sales = result.all()
58
 
59
  # Calculate totals
60
- total_revenue = sum(day.total_sales for day in daily_sales)
61
- total_orders = sum(day.order_count for day in daily_sales)
62
  avg_order_value = total_revenue / total_orders if total_orders > 0 else 0
63
 
64
  return {
65
  "daily_sales": [
66
- {"date": day.date, "total_sales": day.total_sales, "order_count": day.order_count}
 
 
 
 
67
  for day in daily_sales
68
  ],
69
- "total_revenue": total_revenue,
70
  "total_orders": total_orders,
71
- "average_order_value": avg_order_value
72
  }
73
 
74
  @router.get("/products")
 
11
 
12
  @router.get("/sales")
13
  async def get_sales_analytics(
14
+ start_date: Optional[str] = Query(None),
15
+ end_date: Optional[str] = Query(None),
16
  branch_id: Optional[int] = Query(None, description="Filter analytics by branch"),
17
  current_user: User = Depends(get_current_active_user),
18
  db: AsyncSession = Depends(get_db)
19
  ) -> Dict[str, Any]:
20
+ # Parse dates or use last 30 days as default
21
+ try:
22
+ end = datetime.now() if not end_date else datetime.fromisoformat(end_date)
23
+ start = (end - timedelta(days=30)) if not start_date else datetime.fromisoformat(start_date)
24
+ except ValueError:
25
+ # Handle invalid date format
26
+ end = datetime.now()
27
+ start = end - timedelta(days=30)
28
 
29
  # Build query conditions
30
  conditions = [
31
+ Order.created_at.between(start, end),
32
  Order.status.in_(['completed', 'delivered'])
33
  ]
34
 
 
41
  )
42
  conditions.append(Order.branch_id == branch_id)
43
  elif not current_user.is_superuser:
 
44
  conditions.append(Order.branch_id == current_user.branch_id)
45
 
46
  # Daily sales query
 
60
  daily_sales = result.all()
61
 
62
  # Calculate totals
63
+ total_revenue = sum(day.total_sales or 0 for day in daily_sales)
64
+ total_orders = sum(day.order_count or 0 for day in daily_sales)
65
  avg_order_value = total_revenue / total_orders if total_orders > 0 else 0
66
 
67
  return {
68
  "daily_sales": [
69
+ {
70
+ "date": day.date.isoformat(),
71
+ "total_sales": float(day.total_sales or 0),
72
+ "order_count": day.order_count or 0
73
+ }
74
  for day in daily_sales
75
  ],
76
+ "total_revenue": float(total_revenue),
77
  "total_orders": total_orders,
78
+ "average_order_value": float(avg_order_value)
79
  }
80
 
81
  @router.get("/products")
app/db/__pycache__/database.cpython-312.pyc CHANGED
Binary files a/app/db/__pycache__/database.cpython-312.pyc and b/app/db/__pycache__/database.cpython-312.pyc differ
 
app/db/database.py CHANGED
@@ -1,59 +1,59 @@
1
- from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
2
- from sqlalchemy.orm import declarative_base
3
- from ..core.config import settings
4
- import contextlib
5
-
6
- # Create async engine with pgbouncer configuration
7
- async_engine = create_async_engine(
8
- "postgresql+asyncpg://postgres.mqyrkmsdgugdhxiucukb:Lovyelias5584.@aws-0-eu-central-1.pooler.supabase.com:6543/postgres",
9
- echo=True,
10
- future=True,
11
- pool_pre_ping=True,
12
- connect_args={
13
- "statement_cache_size": 0, # Required for pgbouncer
14
- "prepared_statement_cache_size": 0 # Disable prepared statement cache
15
- }
16
- )
17
-
18
- # Create async session factory
19
- AsyncSessionLocal = async_sessionmaker(
20
- bind=async_engine,
21
- class_=AsyncSession,
22
- expire_on_commit=False
23
- )
24
-
25
- # Create declarative base for models
26
- Base = declarative_base()
27
-
28
- # Database dependency for FastAPI routes
29
- async def get_db():
30
- async with AsyncSessionLocal() as session:
31
- try:
32
- yield session
33
- finally:
34
- await session.close()
35
-
36
- # Database access for background tasks and services
37
- class Database:
38
- def __init__(self):
39
- self._session_factory = AsyncSessionLocal
40
-
41
- @contextlib.asynccontextmanager
42
- async def session(self):
43
- """Get a database session with automatic commit/rollback"""
44
- session = self._session_factory()
45
- try:
46
- yield session
47
- await session.commit()
48
- except:
49
- await session.rollback()
50
- raise
51
- finally:
52
- await session.close()
53
-
54
- async def get_session(self):
55
- """Get a session for manual management"""
56
- return self._session_factory()
57
-
58
- # Create singleton instance for database access
59
- db = Database()
 
1
+ from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
2
+ from sqlalchemy.orm import declarative_base
3
+ from ..core.config import settings
4
+ import contextlib
5
+
6
+ # Create async engine with pgbouncer configuration
7
+ async_engine = create_async_engine(
8
+ "postgresql+asyncpg://postgres.mqyrkmsdgugdhxiucukb:Lovyelias5584.@aws-0-eu-central-1.pooler.supabase.com:6543/postgres",
9
+ echo=True,
10
+ future=True,
11
+ pool_pre_ping=True,
12
+ connect_args={
13
+ "statement_cache_size": 0, # Required for pgbouncer
14
+ "prepared_statement_cache_size": 0 # Disable prepared statement cache
15
+ }
16
+ )
17
+
18
+ # Create async session factory
19
+ AsyncSessionLocal = async_sessionmaker(
20
+ bind=async_engine,
21
+ class_=AsyncSession,
22
+ expire_on_commit=False
23
+ )
24
+
25
+ # Create declarative base for models
26
+ Base = declarative_base()
27
+
28
+ # Database dependency for FastAPI routes
29
+ async def get_db():
30
+ async with AsyncSessionLocal() as session:
31
+ try:
32
+ yield session
33
+ finally:
34
+ await session.close()
35
+
36
+ # Database access for background tasks and services
37
+ class Database:
38
+ def __init__(self):
39
+ self._session_factory = AsyncSessionLocal
40
+
41
+ @contextlib.asynccontextmanager
42
+ async def session(self):
43
+ """Get a database session with automatic commit/rollback"""
44
+ session = self._session_factory()
45
+ try:
46
+ yield session
47
+ await session.commit()
48
+ except:
49
+ await session.rollback()
50
+ raise
51
+ finally:
52
+ await session.close()
53
+
54
+ async def get_session(self):
55
+ """Get a session for manual management"""
56
+ return self._session_factory()
57
+
58
+ # Create singleton instance for database access
59
+ db = Database()
app/main.py CHANGED
@@ -31,7 +31,7 @@ background_tasks = set()
31
  # Configure CORS
32
  app.add_middleware(
33
  CORSMiddleware,
34
- allow_origins=["*"], # Configure appropriately for production
35
  allow_credentials=True,
36
  allow_methods=["*"],
37
  allow_headers=["*"],
 
31
  # Configure CORS
32
  app.add_middleware(
33
  CORSMiddleware,
34
+ allow_origins=["http://localhost:5173", "http://localhost:3000"],
35
  allow_credentials=True,
36
  allow_methods=["*"],
37
  allow_headers=["*"],