Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
BookingMyHrManagement
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chanachai
BookingMyHrManagement
Commits
4a83b87f
Commit
4a83b87f
authored
May 15, 2025
by
Ooh-Ao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
projectId param dashboard
parent
78aa85f9
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
106 additions
and
52 deletions
+106
-52
admin_dashboard_controller.py
API-Fast/src/controllers/admin_dashboard_controller.py
+103
-49
admin_dashboard_routes.py
API-Fast/src/routes/admin_dashboard_routes.py
+3
-3
No files found.
API-Fast/src/controllers/admin_dashboard_controller.py
View file @
4a83b87f
# myproject/controllers/admin_dashboard_controller.py
from
datetime
import
date
from
typing
import
Optional
from
uuid
import
UUID
from
sqlalchemy
import
select
,
func
,
extract
,
case
from
sqlalchemy.ext.asyncio
import
AsyncSession
from
..models.project
import
Project
from
..models.member
import
Member
from
..models.project_member
import
ProjectMember
from
..models.equipment
import
Equipment
from
..models.project_equipment
import
ProjectEquipment
from
..models.borrow_transaction
import
BorrowTransaction
...
...
@@ -14,85 +19,134 @@ from ..schemas.admin_dashboard_schema import (
async
def
get_admin_dashboard
(
db
:
AsyncSession
,
start_date
:
date
,
end_date
:
date
end_date
:
date
,
project_id
:
Optional
[
UUID
]
=
None
):
# 1) Summary Cards
total_members
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Member
))
prev_members
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Member
)
.
where
(
Member
.
createdAt
.
between
(
start_date
.
replace
(
year
=
start_date
.
year
-
1
),
start_date
))
)
total_projects
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Project
))
prev_projects
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Project
)
.
where
(
Project
.
createdAt
.
between
(
start_date
.
replace
(
year
=
start_date
.
year
-
1
),
start_date
))
)
total_equips
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Equipment
))
prev_equips
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Equipment
)
.
where
(
Equipment
.
createdAt
.
between
(
start_date
.
replace
(
year
=
start_date
.
year
-
1
),
start_date
))
)
# --- 1) SUMMARY CARDS ---
if
project_id
:
# สมาชิกในโปรเจ็กต์
total_members
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
ProjectMember
)
.
where
(
ProjectMember
.
projectId
==
project_id
)
)
prev_members
=
0
# โครงการเดียว
total_projects
=
1
prev_projects
=
0
# อุปกรณ์ในโครงการ (นับ distinct equipment)
total_equips
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
ProjectEquipment
)
.
where
(
ProjectEquipment
.
projectId
==
project_id
)
)
prev_equips
=
0
else
:
total_members
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Member
))
prev_members
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Member
)
.
where
(
Member
.
createdAt
.
between
(
start_date
.
replace
(
year
=
start_date
.
year
-
1
),
start_date
))
)
total_projects
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Project
))
prev_projects
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Project
)
.
where
(
Project
.
createdAt
.
between
(
start_date
.
replace
(
year
=
start_date
.
year
-
1
),
start_date
))
)
total_equips
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Equipment
))
prev_equips
=
await
db
.
scalar
(
select
(
func
.
count
())
.
select_from
(
Equipment
)
.
where
(
Equipment
.
createdAt
.
between
(
start_date
.
replace
(
year
=
start_date
.
year
-
1
),
start_date
))
)
summary
=
[
SummaryCard
(
label
=
"จำนวนผู้ใช้งานทั้งหมด"
,
value
=
total_members
,
change
=
(
total_members
-
prev_members
)
/
prev_members
*
100
if
prev_members
else
0
),
SummaryCard
(
label
=
"จำนวนโครงการทั้งหมด"
,
value
=
total_projects
,
change
=
(
total_projects
-
prev_projects
)
/
prev_projects
*
100
if
prev_projects
else
0
),
SummaryCard
(
label
=
"จำนวนอุปกรณ์ทั้งหมด"
,
value
=
total_equips
,
change
=
(
total_equips
-
prev_equips
)
/
prev_equips
*
100
if
prev_equips
else
0
),
SummaryCard
(
label
=
"จำนวนผู้ใช้งาน"
,
value
=
total_members
,
change
=
(
total_members
-
prev_members
)
/
prev_members
*
100
if
prev_members
else
0
),
SummaryCard
(
label
=
"จำนวนโครงการ"
,
value
=
total_projects
,
change
=
(
total_projects
-
prev_projects
)
/
prev_projects
*
100
if
prev_projects
else
0
),
SummaryCard
(
label
=
"จำนวนอุปกรณ์"
,
value
=
total_equips
,
change
=
(
total_equips
-
prev_equips
)
/
prev_equips
*
100
if
prev_equips
else
0
),
]
# 2) Monthly Trends (bar chart) ยืม vs คืน
# Helper: build a SQLAlchemy filter for this project
def
pe_filter
(
q
):
return
q
.
where
(
ProjectEquipment
.
projectId
==
project_id
)
if
project_id
else
q
def
bt_filter
(
q
):
if
project_id
:
# borrowTransaction.pe_id in those of this project
q
=
q
.
where
(
BorrowTransaction
.
peId
.
in_
(
select
(
ProjectEquipment
.
peId
)
.
where
(
ProjectEquipment
.
projectId
==
project_id
)
))
return
q
# --- 2) MONTHLY TRENDS ---
stmt
=
(
select
(
extract
(
'month'
,
BorrowTransaction
.
created_at
)
.
label
(
'm'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
!=
'returned'
,
1
),
else_
=
0
))
.
label
(
'borrowed'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
==
'returned'
,
1
),
else_
=
0
))
.
label
(
'returned'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
!=
'returned'
,
1
),
else_
=
0
)
)
.
label
(
'borrowed'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
==
'returned'
,
1
),
else_
=
0
)
)
.
label
(
'returned'
),
)
.
where
(
BorrowTransaction
.
created_at
.
between
(
start_date
,
end_date
))
.
group_by
(
'm'
)
.
order_by
(
'm'
)
)
stmt
=
bt_filter
(
stmt
)
stmt
=
stmt
.
group_by
(
'm'
)
.
order_by
(
'm'
)
rows
=
(
await
db
.
execute
(
stmt
))
.
all
()
monthly_trends
=
[
TrendItem
(
period
=
date
(
1900
,
int
(
m
),
1
)
.
strftime
(
'
%
b'
),
borrowed
=
int
(
b
),
returned
=
int
(
r
))
TrendItem
(
period
=
date
(
1900
,
int
(
m
),
1
)
.
strftime
(
'
%
b'
),
borrowed
=
int
(
b
),
returned
=
int
(
r
)
)
for
m
,
b
,
r
in
rows
]
# 3) Equipment Distribution (pie chart)
stmt2
=
(
select
(
Equipment
.
equipmentName
,
func
.
coalesce
(
func
.
sum
(
ProjectEquipment
.
quantity_in_project
),
0
)
.
label
(
'count'
)
)
.
join
(
ProjectEquipment
,
Equipment
.
equipmentId
==
ProjectEquipment
.
equipmentId
)
.
group_by
(
Equipment
.
equipmentName
)
)
# --- 3) EQUIPMENT DISTRIBUTION ---
stmt2
=
select
(
Equipment
.
equipmentName
,
func
.
coalesce
(
func
.
sum
(
ProjectEquipment
.
quantity_in_project
),
0
)
.
label
(
'count'
)
)
.
join
(
ProjectEquipment
,
Equipment
.
equipmentId
==
ProjectEquipment
.
equipmentId
)
stmt2
=
pe_filter
(
stmt2
)
.
group_by
(
Equipment
.
equipmentName
)
rows2
=
(
await
db
.
execute
(
stmt2
))
.
all
()
equipment_distribution
=
[
PieSlice
(
category
=
name
,
count
=
int
(
cnt
))
for
name
,
cnt
in
rows2
]
#
4) Borrow/Return Line (line chart)
#
--- 4) BORROW/RETURN LINE ---
stmt3
=
(
select
(
extract
(
'month'
,
BorrowTransaction
.
created_at
)
.
label
(
'm'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
!=
'returned'
,
1
),
else_
=
0
))
.
label
(
'borrowed'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
==
'returned'
,
1
),
else_
=
0
))
.
label
(
'returned'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
!=
'returned'
,
1
),
else_
=
0
)
)
.
label
(
'borrowed'
),
func
.
sum
(
case
((
BorrowTransaction
.
status
==
'returned'
,
1
),
else_
=
0
)
)
.
label
(
'returned'
),
)
.
where
(
BorrowTransaction
.
created_at
.
between
(
start_date
,
end_date
))
.
group_by
(
'm'
)
.
order_by
(
'm'
)
)
stmt3
=
bt_filter
(
stmt3
)
.
group_by
(
'm'
)
.
order_by
(
'm'
)
rows3
=
(
await
db
.
execute
(
stmt3
))
.
all
()
borrow_return_line
=
[
TrendItem
(
period
=
date
(
1900
,
int
(
m
),
1
)
.
strftime
(
'
%
b'
),
borrowed
=
int
(
b
),
returned
=
int
(
r
))
TrendItem
(
period
=
date
(
1900
,
int
(
m
),
1
)
.
strftime
(
'
%
b'
),
borrowed
=
int
(
b
),
returned
=
int
(
r
)
)
for
m
,
b
,
r
in
rows3
]
...
...
API-Fast/src/routes/admin_dashboard_routes.py
View file @
4a83b87f
...
...
@@ -3,24 +3,24 @@ from fastapi import APIRouter, Depends, Query
from
sqlalchemy.ext.asyncio
import
AsyncSession
from
datetime
import
date
,
timedelta
from
typing
import
Optional
from
uuid
import
UUID
from
..config.database
import
get_db
from
..controllers.admin_dashboard_controller
import
get_admin_dashboard
from
..schemas.admin_dashboard_schema
import
AdminDashboardResponse
router
=
APIRouter
(
prefix
=
"/admin/dashboard"
,
tags
=
[
"AdminDashboard"
])
@router.get
(
""
,
response_model
=
AdminDashboardResponse
)
async
def
admin_dashboard
(
start_date
:
Optional
[
date
]
=
Query
(
None
,
description
=
"YYYY-MM-DD"
),
end_date
:
Optional
[
date
]
=
Query
(
None
,
description
=
"YYYY-MM-DD"
),
project_id
:
Optional
[
UUID
]
=
Query
(
None
,
description
=
"Filter by project ID"
),
db
:
AsyncSession
=
Depends
(
get_db
)
):
# กำหนด default ช่วง 1 ปีย้อนหลังถ้าไม่ส่งมา
if
not
end_date
:
end_date
=
date
.
today
()
if
not
start_date
:
start_date
=
end_date
-
timedelta
(
days
=
365
)
return
await
get_admin_dashboard
(
db
,
start_date
,
end_date
)
return
await
get_admin_dashboard
(
db
,
start_date
,
end_date
,
project_id
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment